Oracle LOB字段在PHP PDO_OCI下的解决方法

在我们的项目中,使用了Oracle做为数据库,PDO_OCI 作为数据库驱动。

项目中需要使用到CLOB字段来存储大量的数据,什么CLOB?我们先来看看Oracle官方的说明

Oracle 提供了以下 LOB 类型:
* BLOB,用于存储二进制数据
* CLOB,用于使用数据库字符集编码存储字符数据
* NCLOB,用于使用国家字符集存储 Unicode 字符数据。 注意,您将在本文中使用的 PHP OCI8 扩展当前不支持 NCLOB。
* BFILE,用于引用存在于操作系统的文件系统中的外部文

在PHP中,如果你想把LOB字段当做普通的字段来存取数据,会导致程序出错,甚至包括 httpd.exe 的非法错误。PHP的 OCI8 扩展提供了这一字段的支持,但仅提供了 BLOB、CLOB、BFILE 三种类型字段的支持(使用方法请参考Oracle官方文档),但 PDO_OCI 并没有提供这样的支持,那么我们如何解决这个问题?

通过查询相关文档找到了以下的解决办法,由于项目中使用了 Zend_Framework,那么我就以 Zend_Framework 来解决问题,关于 PHP 中的使用方法请参考PHP手册 PDO Functions - Large Objects (LOBs) 一节:

$stmt = new Zend_Db_Statement_Pdo($db, $sql);
$stmt->bindColumn('CONTENT', $content, PDO::PARAM_LOB);
$stmt->bindColumn('TITLE', $title, PDO::PARAM_STR);
$stmt->execute();
while ($row = $stmt->fetch(PDO::FETCH_BOUND)) {
    
echo '<h1>' . $title . '</h1>';
    
echo stream_get_contents($content) .'<hr />';
}

这里,使用到了 PDOStatement->bindColumn() 的方法,参阅相关资料得知:PDO::PARAM_LOB 可用于大文本对像字段,并使用 PDO::FETCH_BOUND 模式来进行存取,这是关于 PDO::PARAM_LOB 的说明:

PDO::PARAM_LOB (integer)
Represents the SQL large object data type.

这样的方法需要要求我们对所需要存取的字段都进行绑定,因此在例子中还使用了 PDO::PARAM_STR,但是那将会是一件非常烦琐的事。因此在项目中我们使用了 OCI8 的扩展来完成工作,这样工作变得简单很多,这也是Oracle官方给出的使用方法,取出数据时用到了一个 load() 的方法,至于更详细的用法就不在这里啰嗦了,大家可以自己参考一下文档。

相关的 Zend_Framework 代码如下:

$stmt = new Zend_Db_Statement_Oracle($db, $sql);
$stmt->execute();
while ($row = $stmt->fetch(Zend_Db::FETCH_ASSOC)) {
    
echo '<h1>' . $row['TITLE'] . '</h1>';
    
echo $row['CONTENT']->load() . '<hr />';
}

显然,上面的方法要方便很多。

另外,Zend Framework 对 Oracle 的 OCI 驱动的 lastInsertId (sequence) 的BUG还没有修正,如果大家在使用中出现问题,请找到 Zend_Db_Adapter_Oracle 第218行的 $sequenceName .= ‘_seq’; ,修正为 $sequenceName .= ‘_SEQ’; 即可(PS:这里需要大写,也不知道他们到底有没有做过测试,估计是没有的)。

口误笑话 @_@~

1 单位祝词,一位领导说:“祝大家身体愉快……”憋住,没词了。

2 有一次帮老板订酒店,想问问人家有没有什么免费上网之类的服务,却怎么也想不出来怎么说好,于是就问对方:“请问,你们这里有什么特殊服务吗?“
对方:“什么?特殊服务??我们是正规酒店!”
-__-!!!!

3 宿舍老四下床找了半天拖鞋,没有,问大家:为什么我的拖鞋哪里去了?

4 逛街中,突然朋友惊呼:“哇!‘处女书店’!”我大惊,抬头一看,一块匾额,上书四个大字
——外文书店-__-!

5 我有次去买羊肉串
伸出4个手指对老板说“来3根羊肉串”
老板蒙了“几根?”
我又伸出3个手指说“4根”……

6 我们的总经理姓周,一次他打电话来,我正开车,一紧张张口就说:”周总理……”

7 本人姓朱,管理单位机房。有次有人打我手机:“鸡科长,你在猪房吗?”当时狂骂那家伙一顿

8 在食堂排队,听见旁边一男生说:“师傅,来碗‘子弹菜花’汤!”(紫菜蛋花汤)哈哈,笑得我喷汤了。

9 某日在米线店吃饭上得很慢很饿
终于按耐不住拍桌咆哮之,本来是想说再不上米线我就把桌子掀了!
结果说成:”老板!!!!再不上米线我就把桌子吃了!!!!”
全店沉默3秒后爆笑到桌子下面……丢人……

10 爸妈吵架,我爸气的说了句:”我给你滚出去!”

11 高中的时候打篮球,A得球后,无私的传给了B,B轻松进球.过了一会,B得球,A大声喊着把球传给他.B却自己把球投出.结果A大怒喊到:刚才真是瞎了我的狗眼……
全场笑晕

12 印象里小学时的班长极其严肃,一次自习课,教室里人声鼎沸,班长维护了几次秩序之后终于忍无可忍,站起来一拍桌子怒吼道:谁再吵,把他嘴打断!!!……全班肃静

13 大学的时候,我们问一个哥们曼联的战况如何,他激动的说:“曼联输了,贝克汉姆领到两张黄盘下场了!”

14 没有金箍棒就别揽瓷器活

15 上大学时,一老师讲课,讲到一种新型的材料,说:“这种材料的性功能是旧材料不可比拟的……啊不对,性能和功能……”

16 刚上大学,军训,连长不知道是哪里的口音,喊口令——“向左钻!”“向右钻!”
(未完,点击阅读全文)

Theme Brought to you by Directory Journal and Elegant Directory