oraclephp類
A. 用php操縱Oracle的LOB類型的數據
《PHP+Oracle(OCI) 初步》中講了如何用PHP中的OCI函數來連接Oracle資料庫 執行一些SQL查詢及關閉資料庫連接 本文將講述另一個難度稍大的問題 用PHP的OCI函數來操縱Oracle的LOB欄位 閱讀本文需要《PHP+Oracle(OCI) 初步》一文中的知識用過Oracle的人都知道 Oracle有一種數據類型叫VARCHAR 用來表示不定長的字元串 VARCHAR 也是Oracle公司推薦使用的類型 但使用VARCHAR 有個問題 最大隻能表示 個字元 也就相當於 個漢字 如果你的程序中某個字元的值要大於 個漢字 用VARCHAR 就不能滿足要求了 這時候 你有兩個選擇 一是用多個VARCHAR 來表示 二是用LOB欄位 這里我們來看看第二個辦法
先來大體了解一下Oracle的LOB欄位 Oracle的LOB類型分為三種 BLOB CLOB和BFILE CLOB稱為字元LOB BLOB和BFILE是用來存儲二進制數據的 CLOB和BLOB的最大長度是 GB 它們把值存放在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欄位中插入值 一般情況下 有如下的幾步 .先分析一個INSERT語句 返回一個LOB的描述符 .用OCI函數生成一個本地的LOB對象 .將LOB對象綁定到LOB描述符上 .執行INSERT語句 .給LOB對象賦值 .釋放LOB對象和SQL語句句柄
下面的這個例子是把用戶上傳的圖片文件存放到BLOB(或BFILE中 操作稍蠢物有不同)中 首先要建一個表 結構如下 CREATE TABLE PICTURES ( ID NUMBER DESCRIPTION VARCHAR ( ) MIME VARCHAR ( ) 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 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欄位的值最少要 個字元 所以在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= ALT= 放在Oracle LOB中的圖片 >
三 查詢
前面已經提了下 對於Oracle的LOB欄位是不能用LIKE進行匹配的 怎麼辦呢?其實並不復雜 Oracle有一個匿名的程序包 叫DBMS_LOB 裡面有所有的操作LOB所需的過程
假設有象這樣一個表: CREATE TABLE ARTICLES ( ID NUMBER TITLE VARCHAR ( ) CONTENT CLOB );
文章的內容放在CONTENT欄位中
現在我們要找出所以內容中包含 PHP中文用戶 的文章 可以這么來做
<?php $conn = OCILogon($user $password $SID); //WHERE子句中用了DBMS_LOB INSTR過程 它有四個參數 前面兩個分別表示LOB的定位符(可以直接用欄位表示)和要查找的字元串 後面兩個分別表示開始的偏移量和出現的次數 要注意的是必須判斷它的返回值 也就是要大於 $stmt = OCIParse($conn SELECT * FROM ARTICLES WHERE DBMS_LOB INSTR(CONTENT PHP中文用戶 ) > ); OCIExecute($stmt); if (OCIFetchInto($stmt $result OCI_ASSOC+OCI_RETURN_LOBS)) { } OCIFreeStatement($stmt); OCILogoff($conn); ?>
Oracle還提供了許多用來操作LOB數據的過程 如LENGTH SUBSTR等等 至於它們的詳細用法 可以考慮Oracle的開發手冊
lishixin/Article/program/PHP/201311/21377
B. 求PHP與ORACLE資料庫連接的代碼
強烈推薦使用ADODB庫鏈接資料庫。
如果一定要使用PHP內置函數,那麼:
如果PHP版本>5.0,那麼使用下面的函數
oci_connect
(
username,
password
,
dbname
)
例子:
<?php
$conn
=
oci_connect('hr',
'hr',
'orcl');
//
建立連接
if
(!$conn)
{
$e
=
oci_error();
print
htmlentities($e['message']);
exit;
}
$query
=
'SELECT
*
FROM
DEPARTMENTS';
//
查詢語句
$stid
=
oci_parse($conn,
$query);
//
配置SQL語句,准備執行
if
(!$stid)
{
$e
=
oci_error($conn);
print
htmlentities($e['message']);
exit;
}
$r
=
oci_execute($stid,
OCI_DEFAULT);
//
執行SQL。OCI_DEFAULT表示不要自動commit
if(!$r)
{
$e
=
oci_error($stid);
echo
htmlentities($e['message']);
exit;
}
//
列印執行結果
print
'<table
border="1">';
while($row
=
oci_fetch_array($stid,
OCI_RETURN_NULLS))
{
print
'<tr>';
foreach($row
as
$item)
{
print
'<td>'.($item?htmlentities($item):' ').'</td>';
}
print
'</tr>';
}
print
'</table>';
oci_close($conn);
?>