|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
左手拿着MOTOLOLA右手拿着NOKIA,要多潇洒,有多潇洒,哈哈,终于学会了,但是可能这个时候,又会有人不经意的拍拍肩膀对你说:哥们,别高兴的太早,你还是菜鸟,离学会还差着一大截呢!oracle|数据 《PHP+Oracle(OCI) 初步》中讲了若何用PHP中的OCI函数来毗连Oracle数据库,履行一些SQL查询及封闭数据库毗连。本文将讲述另外一个难度稍大的成绩:用PHP的OCI函数来把持Oracle的LOB字段。浏览本文需求《PHP+Oracle(OCI) 初步》一文中的常识。
用过Oracle的人都晓得,Oracle有一种数据类型叫VARCHAR2,用来暗示不定长的字符串。VARCHAR2也是Oracle公司保举利用的类型。但利用VARCHAR2有个成绩:最大只能暗示4000个字符,也就相当于2000个汉字。假如你的法式中某个字符的值要大于20002个汉字,用VARCHAR2就不克不及知足请求了。这时候候,你有两个选择,一是用多个VARCHAR2来暗示,二是用LOB字段。这里咱们来看看第二个举措。
先来大体懂得一下Oracle的LOB字段。Oracle的LOB类型分为三种:BLOB,CLOB和BFILE。CLOB称为字符LOB,BLOB和BFILE是用来存储二进制数据的。CLOB和BLOB的最大长度是4GB,它们把值寄存在Oracle数据库中。BFILE和BLOB相似,但它把数据放在内部的文件中,所以它又称为内部BLOB(External BLOB)。
我想,咱们对MYSQL应当都不会生疏。MYSQL中也有相似的数据类型,如TEXT和BLOB。在PHP的MYSQL函数中,对TEXT/BLOB的操作是直接的,就象其它类型的数据一样。但在Oracle中,情形就纷歧样了。Oracle把LOB看成一种特别的数据类型来处置,在操作上不克不及用惯例的办法。好比,不克不及在INSERT语句中直接把值拔出到LOB字段中,也不克不及用LIKE停止查找。
上面就经由过程几个例子来讲明若何用PHP的OCI函数来拔出,掏出和查询LOB数据。
拔出
不克不及直接用INSERT语句向LOB字段中拔出值。普通情形下,有以下的几步:
1 先剖析一个INSERT语句,前往一个LOB的描写符
2 用OCI函数生成一个当地的LOB对象
3 将LOB对象绑定到LOB描写符上
4 履行INSERT语句
5 给LOB对象赋值
6 释放LOB对象和SQL语句句柄
上面的这个例子是把用户上传的图片文件寄存到BLOB(或BFILE中,操作稍有分歧)中。
起首要建一个表,布局以下:
CREATE TABLE PICTURES (
ID NUMBER,
DESCRIPTION VARCHAR2(100),
MIME VARCHAR2(128),
PICTURE BLOB
);
假如要完成ID的主动增添,再建一个SEQUENCE:
CREATE SEQUENCE PIC_SEQ;
然后是用来处置数据的PHP法式代码。
<?php
//创立Oracle数据库毗连
$conn = OCILogon($user, $password, $SID);
//提交SQL语句给Oracle
//在这里要注重的两点:一是用EMPTY_BLOB()函数。这是Oracle的外部函数,前往一个LOB的定位符。在拔出LOB时,只能用这个举措师长教师成一个空的LOB定位符,然后对这个定位符停止操作。EMPTY_BLOB()函数是针对BLOB类型的,对应于CLOB的是EMPTY_CLOB()。二是RETURNING前面的局部,把picture前往,让PHP的OCI函数可以处置。
$stmt = OCIParse($conn,"INSERT INTO PICTURES (id, description, picture)
VALUES (pic_seq.NEXTVAL, '$description', '$lob_upload_type', EMPTY_BLOB()) RETURNING picture INTO :PICTURE");
//生成一个当地LOB对象的描写符。注重函数的第二个参数:OCI_D_LOB,暗示生成一个LOB对象。其它能够的还有OCI_D_FILE和OCI_D_ROWID,分离对应于BFILE和ROWID对象。
$lob = OCINewDescriptor($conn, OCI_D_LOB);
//将生成的LOB对象绑定到后面SQL语句前往的定位符上。
OCIBindByName($stmt, ':PICTURE', &$lob, -1, OCI_B_BLOB);
OCIExecute($stmt);
//向LOB对象中存入数据。由于这里的源数据是一个文件,所以直接用LOB对象的savefile()办法。LOB对象的其它办法还有:save()和load(),分离用来保留和掏出数据。但BFILE类型只要一个办法就是save()
if($lob->savefile($lob_upload)){
OCICommit($conn);
echo "上传胜利<br>";
}else{
echo "上传掉败<br>";
}
//释放LOB对象
OCIFreeDesc($lob);
OCIFreeStatement($stmt);
OCILogoff($conn);
?>
还有一个要注重的中央:LOB字段的值起码要1个字符,所以在save()或savefile()之前,要确保值不克不及为空。不然,Oracle会失足。
掏出
对一个LOB中掏出数据,有两种举措。一是生成一个LOB对象,然后绑定到一条SELECT语句前往的定位符上,再用LOB对象的load()办法掏出数据;二是直接用PHP的OCIFetch***函数。第一种办法比第二种办法要费事很多,所以我直接说说第二种办法。
仍是用下面的表。
<?php
$conn = OCILogon($user, $password, $SID);
$stmt = OCIParse($conn,"SELECT * FROM PICTURES WHERE ID=$pictureid");
OCIExecute($stmt);
//奥密就在PCIFetchInfo的第三个参数上:OCI_RETURN_LOBS。第三个参数是FETCH的形式,假如OCI_RETURN_LOBS,就直接把LOB的值放到了局数组中,而不是LOB定位符,也就不必LOB对象的load()办法了。
if (OCIFetchInto($stmt, $result, OCI_ASSOC+OCI_RETURN_LOBS))
{
echo "Content-type: " . StripSlashes($result[MIME]);
echo StripSlashes($result[PICTURE]);
}
OCIFreeStatement($stmt);
OCILogoff($conn);
?>
这个法式用来显示放在LOB中的数据(图片)。挪用办法(假定剧本名是getpicture.php):
<IMG SRC="getpicture.php?pictureid=99" ALT="放在Oracle LOB中的图片">
查询
后面已提了下,关于Oracle的LOB字段是不克不及用LIKE停止婚配的。怎样办呢?其实其实不庞杂,Oracle有一个匿名的法式包,叫DBMS_LOB,外面有一切的操作LOB所需的进程。
假定有象如许一个表:
CREATE TABLE ARTICLES (
ID NUMBER,
TITLE VARCHAR2(100),
CONTENT CLOB
);
文章的内容放在CONTENT字段中。
如今咱们要找出所之内容中包括"PHP中文用户"的文章,可以这么来做:
<?php
$conn = OCILogon($user, $password, $SID);
//WHERE子句顶用了DBMS_LOB.INSTR进程。它有四个参数,后面两个分离暗示LOB的定位符(可以直接用字段暗示)和要查找的字符串;前面两个分离暗示入手下手的偏移量和呈现的次数。要注重的是必需判别它的前往值,也就是要大于0。
$stmt = OCIParse($conn,"SELECT * FROM ARTICLES WHERE DBMS_LOB.INSTR(CONTENT, 'PHP中文用户', 1, 1) > 0");
OCIExecute($stmt);
if (OCIFetchInto($stmt, $result, OCI_ASSOC+OCI_RETURN_LOBS))
{
...
}
OCIFreeStatement($stmt);
OCILogoff($conn);
?>
Oracle还供应了很多用来操作LOB数据的进程,如LENGTH, SUBSTR等等。至于它们的具体用法,可以思索Oracle的开辟手册。
关于对Oracle数据库中的LOB类型的数据的操作,就说这么多了。因为我接触Oracle工夫不长,本文中能够还会有毛病,接待人人品评斧正。 不懂的问题有很多高手帮你解决。但不要认为你是新手,就不能帮助别人,比如今天你学会了怎样安装PHP,明天还可能有朋友会问这个问题,你就可以给他解答,不要认为这是浪费时间,忙别人其实就是帮助自己。 |
|