国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > Oracle > 正文

Php操作oracle數據庫指南-本人原創,經驗總結,不能不看

2024-08-29 13:32:29
字體:
來源:轉載
供稿:網友
本人由于工作關系使用oracle數據庫,發現這里用的人不多,但時常發現有人提的關于php操作oracle數據庫的問題得不到回答,我也曾問過幾個,但也無人響應,因此決定把本人在工作中積攢起來的一些技巧、經驗奉獻出來,希望對使用oracle數據庫的人有所幫助。
一、配置環境:
訪問oracle8以上的數據庫需要用到oracle8 call-interface(oci8)。這個擴展模塊需要oracle8 的客戶端函數庫,因此需要你要連接遠程oracle數據庫的話,還要裝上oracle的客戶端軟件-可以到oracle網站上免費下載- http://www.oracle.com,這是許多初學者常常忽略的,因此如果看了這篇文章,就不要在論壇上再提“為什么我連接不上oracle數據庫”之類的問題了。
(1)首先確認安裝了oracle8i客戶端,然后用net8 assistant(客戶端軟件提供)建立一個服務命名,注意服

務名是oracle數據庫的sid,可查詢initsid文件里的server_names得到。
(2)在php.ini中把 ;extension=php_oci8.dll 前面的注釋符號“;”去掉,使php能夠加載支持oracle的模塊

。并把php_oci8.dll拷貝到你的windows2000 server安裝目錄下的system32子目錄。如d:/winnt/system32,重

新啟動你的機器。
(3)寫個測試文件試一下是否能正確連接(假如服務名sid是test):
這里scott用戶是oracle自帶的無須你自己建立了,只要把下面這個文件放到你的web根目錄就可以了。如果顯

示到數據庫中的數據,則說明連接正常,如果不行,你還要檢查前幾步有哪些地方做錯了。
test.php
<?
$dbconn=ocilogon("scott","tiger","test");
$sql ="select * from emp";
$stmt = ociparse($dbconn, $sql);
if(!$stmt) {
echo "<h1>error - could not parse sql statement.</h1>";
exit;
}
ociexecute($stmt);
while( ocifetchinto($stmt, &$result_array) )
{
echo

"empno=$result_array[0];ename=$result_array[1];job=$result_array[2];mgr=$result_array[3]<br>";
}
?>

二、用php執行oracle存儲過程
(1)用sqlplus連接后,建立一個存儲過程:
create or replace procedure inoutdemo (
par_in in varchar2,
par_in_out in out varchar2,
par_out out varchar2)
is
begin
par_out := par_in;
par_in_out := par_in || ' ' || par_in_out;
end;
(2)php文件:
sptest.php
<?
//:in是輸入變量;:inout是輸入輸出變量;:out是輸出變量,具體解釋請參考oracle的pl/sql手冊
$conn=ocilogon("scott","tiger","test");
$stmt = ociparse($conn,"begin inoutdemo(:in,:inout,:out); end;");
ocibindbyname($stmt,":in",$in,32);
ocibindbyname($stmt,":inout",$inout,32);
ocibindbyname($stmt,":out",$out,32);

$in = "hello ";
$inout = "world!";

ociexecute($stmt);
echo "<br><br>";
echo "in=".$in."<br>";
echo "inout=".$inout."<br>";
echo "out=".$out."<br>";
?>

三、oracle數據庫的分頁
oracle雖然不象mysql有limit可用,十分方便,但也有自己的處理方法,它特殊的rownum對分頁有很重要的作

用。分頁可有很多種方法,其中最常用的是用minus。
如要顯示n1-n2記錄可寫為:
(1)select * from tablename where rownum <= n2 minus select * from tablename where rownum < n1
注意:該語句不能使用order by,否則報錯。
(2)把指針下移的辦法如:
其中:$page是當前頁;$pagesize是每頁顯示的記錄數
for($i=0;$i<($page-1)*$pagesize;$i++)
{
@ocifetch($stmt);
}
然后再用ocifetch($stmt)取出的數據就是你要顯示的記錄了
(3)對于有復雜查詢語句并用order by來排序的,可使用下面方法解決:
select table_name,table_type from( select rownum rowseq,x.* from (select * from cat order by

table_type) x) where rowseq between n1+1 and n2;
本人最喜歡的是第三種,也推薦大家使用,非常方便的啊。呵呵。
其它方法就不介紹了,很麻煩,使用了oracle游標之類的東東,不太適合php使用。

四、特殊字符的插入處理
對于一些字符如單引號'在oracle里是不能用addslashes處理的,但可以使用oracle的chr函數或再加個單引號


如:sql>insert into table values('it'||chr(39)||'s a test'));
或 sql>insert into table values('it''s a test'));
顯示:
it's a test.

五、php和oracle的事務處理
ociexecute()函數:int ociexecute ( int statement [, int mode] )
第二個參數mode共有兩個:缺省為oci_commit_on_success,可省略。oci_default 表示用事務(transation)

提交,不自動提交。
如果你在程序中如果有兩個操作數據庫的語句需要同時成功執行,有一個失敗就要rollback的話,可這樣寫:

$conn=ocilogon($username,$password,$sid);
//first sentence
$sql = "insert into tablename values()";
$stmt=ociparse($conn,$sql);
$result=ociexecute($stmt, oci_default);
if (!$result) {
ocirollback($conn);//不成功則回滾
ocifreestatement($stmt); //釋放資源
ocilogoff($conn);
}

//second sentence
$sql = " update tablename set..";
$stmt=ociparse($conn,$sql);
$result=ociexecute($stmt, oci_default);
if (!$result) {
ocirollback($conn);//不成功則回滾
ocifreestatement($stmt); //釋放資源
ocilogoff($conn);
}


ocicommit($conn);//如果都成功則提交
ocifreestatement($stmt); //釋放資源
ocilogoff($conn);



六、用php操縱oracle的lob類型的數據(含圖片的存儲與顯示處理)
對php程序員來講,oracle最令人頭痛的莫過于使用lob來處理圖片了。
1。php操作blob:
先建立一個表用于保存圖片。用戶上傳的圖片文件存放到blob中
create table pictures (
id number,
imgtype, varchar2(60),
description varchar2(100),
picture blob
);
如果要實現id的自動增加,再建一個sequence:
create sequence pic_seq;

php程序-插入部分:
<?
$conn=ocilogon($username,$password,$sid);
//在這里要注意的兩點:一是用empty_blob()函數。這是oracle的內部函
//數,返回一個lob的定位符。在插入lob時,只能用這個辦法先生成一個
//空的lob定位符,然后對這個定位符進行操作。empty_blob()函數是針
//對blob類型的,對應于clob的是empty_clob()。二是returning后面的
//部分,把picture返回,讓php的oci函數能夠處理。
$stmt = ociparse($conn,"insert into pictures (id, imgtype,description, picture) values

(pic_seq.nextval, '$imgtype','$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〉";
}

//方法二:用save的方法保存
//$fp = fopen($lob_upload, "r");
//$file->save(fread($fp, filesize($lob_upload)));
//fclose($fp );

//釋放lob對象
ocifreedesc($lob);
ocifreestatement($stmt);
ocilogoff($conn);
?>
小技巧:在sqlplus里可用select dbms_lob.getlength(picture) from pictures;查看文件是否已存入到數據

庫或在php程序里用strlen()函數查看。

php程序-顯示部分(getpicture.php):
<?
$conn = ocilogon($username, $password, $sid);
$stmt = ociparse($conn,"select imgtype,picture from pictures where id=$pictureid");
if (ocifetchinto($stmt, $result))
{
header("content-type: ".$result[0]);
echo $result[1]->load();
}
//可用strlen($result[1]->load()) 查看圖片的大小以確定圖片是否正確存入到數據庫。

?>

在需要顯示圖片的地方只要:
<img src="getpicture.php?pictureid=99" alt="放在oracle lob中的圖片">

就能顯示圖片了
有的網上文章寫用返回lob值而非描述符的方法顯示,我沒有試成功,大家可以試下
代碼如下:
if (ocifetchinto($stmt, $result, oci_assoc+oci_return_lobs))
{
echo "content-type: " . stripslashes($result[imgtype]);
echo stripslashes($result[picture]);
}

2。php操作clob:
oracle有一種數據類型叫varchar2,用來表示不定長的字符串。varchar2也是oracle公司推薦使用的類型。但

使用varchar2有個問題:最大只能表示4000個字符,也就相當于2000個漢字。如果你的程序中某個字符串的長

度要大于2000個漢字,用varchar2就不能滿足要求了。這時候,你可以嘗試使用clob。clob和blob的最大長度

是4gb。

下面是示例(參考了php英文版的手冊):
<?
//要保存的文字
$clobtext="different dr2";

//db connection
$conn = ocilogon("user","pw","tns");

//這里原例子使用了一個存儲過程,你也可以用上面操作blob的方法來實現。
//如:$stmt = ociparse($conn,"insert into table (id, clobtext) values (text.nextval,,

empty_clob()) returning clobtext into :clob");


$sql = "begin tempclobtest_package.saveclob(:clob); end;";

$clob = ocinewdescriptor($conn, oci_d_lob);

$stmt = ociparse($conn, $sql);

ocibindbyname ($stmt,':clob', &$clob , -1,oci_b_clob );

if(!ociexecute($stmt, oci_default)) {print_r(ocierror($stmt));}
else{echo "提交成功";}

if($clob->save($clobtext))
{
ocicommit($conn);
echo "提交成功";
}
else
{
print_r(ocierror($stmt));
}

//釋放資源
$clob->free();
ocifreestatement($stmt);
?>


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 教育| 神池县| 临安市| 东丽区| 栖霞市| 锡林浩特市| 逊克县| 达孜县| 彰化市| 阿荣旗| 九台市| 公主岭市| 无锡市| 金乡县| 定远县| 湖口县| 壶关县| 安义县| 富蕴县| 永善县| 桃源县| 舟山市| 珠海市| 旬阳县| 永嘉县| 阿尔山市| 武隆县| 锦屏县| 治多县| 通渭县| 文山县| 建始县| 乐昌市| 高淳县| 琼结县| 琼结县| 盐源县| 建水县| 会同县| 阳春市| 湘乡市|