-

ThinkPHP与Oracle操作实践

PHP

在一次工作的实际项目中,雷雪松操作使用Oracle数据库时遇到很多奇葩的错误。因为第一次使用ThinkPHP操作Oracle数据库,几乎查找了网上所有的资料,测试很多解决办法,搞得心力憔悴。由于网上关于ThinkPHP操作Oracle数据库的资料较少,有些没有实践验证、过时或无效,在前面雷雪松的博客中详细讲解PHP如何连接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;
[cc lnag=”php” escaped=”true”]public function execute($str,$fetchSql=false) {
$bind = $this->bind; //新增这句
$this->initConnect(true);[/cc]

b、在Db\Driver\Oracle.class.php文件中找到foreach ($this->bind as $key => $val) { 这句前面加上 $this->bind = $this->bind ? $this->bind : $bind;
[cc lnag=”php” escaped=”true”]$this->bind = $this->bind ? $this->bind : $bind; //新增这句
foreach ($this->bind as $key => $val) {[/cc]

c、在Db\Driver\Oracle.class.php文件中找到 $this->lastInsID = $this->_linkID->lastInsertId(); 这句修改为$this->lastInsID = $this->lastInsertId($this->table);
[cc lnag=”php” escaped=”true”]//修改:
//$this->lastInsID = $this->_linkID->lastInsertId();
$this->lastInsID = $this->lastInsertId($this->table);[/cc]

d、在Oracle.class.php文件中新增lastInsertId方法
[cc lang=”php” escaped=”true”]/**
* 取得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;
}[/cc]

e、ThinkPHP配置
[cc lang=”php” escaped=”true”]’DB_SEQUENCE_PREFIX’ => ‘seq_’,//序列名前缀,每个表对应的序列应为: 序列名前缀+表名
‘DB_TRIGGER_PREFIX’ => ‘tig_’,//触发器名前缀[/cc]

2、Oracle创建表字段自增,使用序列(sequence)和触发器(trigger)
user为表名
[cc lang=”sql”]—-创建序列
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;[/cc]

3、ThinkPHP如何向Oracle插入时间,Oracle插入时间必须使用to_date()函数
EXP:表达式,支持更复杂的查询情况
[cc lang=”php” escaped=”true”]’update_time’=>array(‘exp’, “to_date(‘”.date(‘Y-m-d H:i:s’).”‘, ‘yyyy-MM-dd HH24:mi:ss’)”)[/cc]

[cc lang=”php” escaped=”true”]”update_time’=>array(‘exp’, ‘sysdate’)[/cc]

4、PHP读取Oracle的date类型数据
[cc lang=”sql”]SELECT to_char(log.time, ‘YYYY-MM-DD HH24:MI:SS’) as addtime FROM log[/cc]

来源:ThinkPHP与Oracle操作实践

6 评论 “ThinkPHP与Oracle操作实践

    卢松松商城 评论:
    2016年9月24日 下午2:28

    看的头疼 完全不懂

    阳光博客 评论:
    2016年9月24日 下午4:38

    博主的文笔很不错,特来拜会。若能有幸能得到博主的回访,必将欣喜若狂。

    廖梓旭 评论:
    2016年9月24日 下午11:49

    会asp.net 和php对比起来好像php更简单~

    苏阔 评论:
    2018年5月3日 下午6:02

    感谢博主。。让我又想起了我之前为何出错。。。终于ok了

    东方小说网 评论:
    2019年5月5日 下午9:31

    好文章!666,学习了

    请看小说阅读网 评论:
    2019年5月11日 上午1:32

    写的太经典了,我竟无言以对。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注