ThinkPHP 3.2.3+ORACLE插入数据BUG修复及支持获取自增Id的上次记录

转载 2016年12月09日 00:56:51

ThinkPHP 3.2.3+ORACLE插入数据BUG修复及支持获取自增Id的上次记录

thinkphp 3.2.3对Oracle的插入数据存在bug,直接导致我今天debug了一晚上。还好找到了在官方社区找到了solution。 以下转自 tp官方社区,感谢lajox的solution。

TP+ORACLE插入数据BUG修复以及获取自增Id支持getLastInsID方法
这些天在做Api接口时候,发现用TP操作Oracle数据库,发现查询修改删除都能执行,
但一旦执行插入操作老是报错。类似问题比如: http://www.thinkphp.cn/bug/3286.html
花了点时间仔细研究一下,发现是BUG.
下面是我的解决办法:
针对版本:ThinkPHP3.2.3
BUG修复
修改文件:Db\Driver\Oracle.class.php

找到 execute方法,
找到:this>initConnect(true);bind = $this->bind; 这句:

public function execute($str,$fetchSql=false) {
    $bind = $this->bind; //新增这句
    $this->initConnect(true);

找到:foreach ($this->bind as $key => $val) { 这句
前面加上 $this->bind = $this->bind ? $this->bind : $bind; 这句:

$this->bind = $this->bind ? $this->bind : $bind; //新增这句
foreach ($this->bind as $key => $val) {

找到 $this->lastInsID = $this->_linkID->lastInsertId(); 这句
将其修改为:

 //修改:
 //$this->lastInsID = $this->_linkID->lastInsertId();
 $this->lastInsID = $this->lastInsertId($this->table);

Oracle.class.php文件中新增以下代码:

/**
 * 取得Oracle最近插入的ID
 * @access public
 */
public function lastInsertId($sequence = '') {
    try {
        $lastInsID = $this->_linkID->lastInsertId();
    } catch(\PDOException $e) {
        //对于驱动不支持PDO::lastInsertId()的情况
        try {
            $lastInsID = 0;
            $seqPrefix = C("DB_SEQUENCE_PREFIX") ? C("DB_SEQUENCE_PREFIX") : 'seq_';
            $sequence = $sequence ? $sequence : $seqPrefix.$this->table;
            $q = $this->query("SELECT {$sequence}.CURRVAL as t FROM DUAL");
            if($q) {
                $lastInsID = $q[0]['t'];
            }
        } catch(\Exception $e) {
            //print "Error!: " . $e->getMessage() . "</br>";
            //exit;
        }
    }
    return $lastInsID;
}

调用方法:
1.数据库配置:

 'DB_PREFIX'=>'tb_',//表名前缀
 'DB_SEQUENCE_PREFIX' => 'seq_',//序列名前缀,每个表对应的序列应为: 序列名前缀+表名
 'DB_TRIGGER_PREFIX' => 'tig_',//触发器名前缀

2.先创建user数据表
表字段:id, username, password

3.然后创建[序列+触发器]

----创建序列
create sequence seq_user
increment by 1 
start with 1
nomaxvalue
nominvalue
nocache;
----创建触发器
create or replace trigger "tig_user"
before insert on tb_user
for each row when(new.id is null)
begin
select seq_user.nextval into :new.id from dual;
end;

4.最后一步,在UserAction中写插入数据代码如下:

$data = array(
    'phone'=>$phone,
    'password'=>md5($password)
);
 $r = M('user')->field(true)->add($data); //执行插入并返回上次插入Id
if($r){
    //$r = M('user')->getLastInsID(); //获取上次插入Id
    echo '上次插入记录:'.$r;
}else{
    $this->error('操作失败');
}

相关文章推荐

重磅 l 全国首例微信三级分销被认定为传销,三级分销“身世”揭秘(下)

全国首例微信三级分销被认定为传销案   2016年4月6日,中国工商报曝出全国首例微信三级分销被认定为传销一案。这在之前案例中从无出现过,所以非常值得大家对照审视。之前所谓的微信传销般所...
  • bjash
  • bjash
  • 2016年06月06日 15:25
  • 3167

laravel前端内容编译:小白的惨痛经历

开启新的laravel旅程。
  • YQXLLWY
  • YQXLLWY
  • 2017年06月22日 14:00
  • 1457

Oracle插入数据时获取自增ID

  • 2008年10月27日 18:03
  • 1KB
  • 下载

让ThinkPHP3.2.3 支持对Oracle LOB数据的操作

让ThinkPHP3.2.3 支持对Oracle LOB数据的操作1. 问题由来PHP2. 配置PHP:OCI8首先,原理是利用PHP OCI8的拓展函数库。所以,必须先把OCI8,和php_oc...

oracle中设置自增主键(id)

  • 2011年06月11日 19:07
  • 40KB
  • 下载

oracle中如何实现ID自增

  • 2011年03月29日 10:38
  • 44KB
  • 下载

mysql插入数据后返回自增ID的方法

mysql插入数据后返回自增ID的方法   mysql和oracle插入的时候有一个很大的区别是,oracle支持序列做id,mysql本身有一个列可以做自增长字段,mysql在插入一条数...

SQL语句:插入数据的同时,返回ID值 (自增)

SQLServer 2000中,有三个比较类似的功能:他们分别是:SCOPE_IDENTITY、IDENT_CURRENT 和 @@IDENTITY,它们都返回插入到 IDENTITY 列中的值。 I...
  • hchyboy
  • hchyboy
  • 2011年05月24日 09:17
  • 640

mysql插入数据后返回自增ID的方法

mysql插入数据后返回自增ID的方法   mysql和oracle插入的时候有一个很大的区别是,oracle支持序列做id,mysql本身有一个列可以做自增长字段,mysql在插入一条数据后,如...
  • ling_du
  • ling_du
  • 2016年04月17日 17:23
  • 3069

mysql 插入数据后返回当前的自增ID方法

存储过程的写法: mysql>create procedure test(         ->in username varchar(50),         ->in passw...
  • Awei922
  • Awei922
  • 2013年12月22日 22:11
  • 1371
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ThinkPHP 3.2.3+ORACLE插入数据BUG修复及支持获取自增Id的上次记录
举报原因:
原因补充:

(最多只允许输入30个字)