核心提示: thinkphp 3.2.3对Oracle的插入数据存在bug,直接导致我今天debug了一晚上。还好找到了在官方社区找到了solution。 以下转自 tp官方社区,感谢lajox的solutio...
thinkphp 3.2.3对Oracle的插入数据存在bug,直接导致我今天debug了一晚上。还好找到了在官方社区找到了solution。 以下转自 tp官方社区,感谢lajox的solution。
TP+ORACLE插入数据BUG修复以及获取自增Id支持getLastInsID方法
这些天在做Api接口时候,发现用TP操作Oracle数据库,发现查询修改删除都能执行,
但一旦执行插入操作老是报错。
花了点时间仔细研究一下,发现是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() . " "; //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('操作失败'); }