在一次工作的实际项目中,使用Oracle数据库时遇到很多奇葩的错误。因为第一次使用ThinkPHP操作Oracle数据库,几乎查找了网上所有的资料,测试很多解决办法,搞得心力憔悴。由于网上关于ThinkPHP操作Oracle数据库的资料较少,有些没有实践验证、过时或无效,现在通过自己实际项目的实践,整理了一些ThinkPHP操作Oracle的常见错误。
1、ThinkPHP插入数据报错“SQLSTATE[IM001]: Driver does not support this function: driver does not support lastInsertId()”
a、在Db\Driver\Oracle.class.php文件中找到execute方法,在$this->initConnect(true); 这句前面加上 $bind = $this->bind;
1 2 3
| public function execute($str,$fetchSql=false) { $bind = $this->bind; //新增这句 $this->initConnect(true); |
b、在Db\Driver\Oracle.class.php文件中找到foreach ($this->bind as $key => $val) { 这句前面加上 $this->bind = $this->bind ? $this->bind : $bind;
1 2
| $this->bind = $this->bind ? $this->bind : $bind; //新增这句 foreach ($this->bind as $key => $val) { |
c、在Db\Driver\Oracle.class.php文件中找到 $this->lastInsID = $this->_linkID->lastInsertId(); 这句修改为$this->lastInsID = $this->lastInsertId($this->table);
1 2 3
| //修改: //$this->lastInsID = $this->_linkID->lastInsertId(); $this->lastInsID = $this->lastInsertId($this->table); |
d、在Oracle.class.php文件中新增lastInsertId方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| /** * 取得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; } |
e、ThinkPHP配置
1 2
| 'DB_SEQUENCE_PREFIX' => 'seq_',//序列名前缀,每个表对应的序列应为: 序列名前缀+表名 'DB_TRIGGER_PREFIX' => 'tig_',//触发器名前缀 |
2、Oracle创建表字段自增,使用序列(sequence)和触发器(trigger)
user为表名
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| ----创建序列 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; |
3、ThinkPHP如何向Oracle插入时间,Oracle插入时间必须使用to_date()函数
EXP:表达式,支持更复杂的查询情况
1
| 'update_time'=>array('exp', "to_date('".date('Y-m-d H:i:s')."', 'yyyy-MM-dd HH24:mi:ss')") |
或
1
| ''update_time'=>array('exp', 'sysdate') |
4、PHP读取Oracle的date类型数据
1
| SELECT to_char(log.time, 'YYYY-MM-DD HH24:MI:SS') AS addtime FROM log |