Php操作oracle數(shù)據(jù)庫(kù)指南-本人原創(chuàng),經(jīng)驗(yàn)總結(jié),不能不看
Jun 21, 2016 am 09:14 AMoracle|數(shù)據(jù)|數(shù)據(jù)庫(kù)|原創(chuàng)
本人由于工作關(guān)系使用Oracle數(shù)據(jù)庫(kù),發(fā)現(xiàn)這里用的人不多,但時(shí)常發(fā)現(xiàn)有人提的關(guān)于PHP操作ORACLE數(shù)據(jù)庫(kù)的問(wèn)題得不到回答,我也曾問(wèn)過(guò)幾個(gè),但也無(wú)人響應(yīng),因此決定把本人在工作中積攢起來(lái)的一些技巧、經(jīng)驗(yàn)奉獻(xiàn)出來(lái),希望對(duì)使用oracle數(shù)據(jù)庫(kù)的人有所幫助。
一、配置環(huán)境:
訪問(wèn)Oracle8以上的數(shù)據(jù)庫(kù)需要用到Oracle8 Call-Interface(OCI8)。這個(gè)擴(kuò)展模塊需要Oracle8 的客戶端函數(shù)庫(kù),因此需要你要連接遠(yuǎn)程O(píng)racle數(shù)據(jù)庫(kù)的話,還要裝上Oracle的客戶端軟件-可以到Oracle網(wǎng)站上免費(fèi)下載- http://www.oracle.com,這是許多初學(xué)者常常忽略的,因此如果看了這篇文章,就不要在論壇上再提“為什么我連接不上Oracle數(shù)據(jù)庫(kù)”之類的問(wèn)題了。
(1)首先確認(rèn)安裝了Oracle8i客戶端,然后用net8 assistant(客戶端軟件提供)建立一個(gè)服務(wù)命名,注意服
務(wù)名是oracle數(shù)據(jù)庫(kù)的sid,可查詢initsid文件里的server_names得到。
(2)在php.ini中把 ;extension=php_oci8.dll 前面的注釋符號(hào)“;”去掉,使php能夠加載支持oracle的模塊
。并把php_oci8.dll拷貝到你的windows2000 server安裝目錄下的system32子目錄。如d:\winnt\system32,重
新啟動(dòng)你的機(jī)器。
(3)寫(xiě)個(gè)測(cè)試文件試一下是否能正確連接(假如服務(wù)名sid是test):
這里scott用戶是Oracle自帶的無(wú)須你自己建立了,只要把下面這個(gè)文件放到你的WEB根目錄就可以了。如果顯
示到數(shù)據(jù)庫(kù)中的數(shù)據(jù),則說(shuō)明連接正常,如果不行,你還要檢查前幾步有哪些地方做錯(cuò)了。
test.php
$dbconn=OCILogon("scott","tiger","test");
$sql ="select * from emp";
$stmt = OCIParse($dbconn, $sql);
if(!$stmt) {
echo "
ERROR - Could not parse SQL statement.
";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]
";
}
?>
二、用PHP執(zhí)行Oracle存儲(chǔ)過(guò)程
(1)用sqlplus連接后,建立一個(gè)存儲(chǔ)過(guò)程:
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是輸出變量,具體解釋請(qǐng)參考Oracle的PL/SQL手冊(cè)
$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 "
";
echo "in=".$in."
";
echo "inout=".$inout."
";
echo "out=".$out."
";
?>
三、Oracle數(shù)據(jù)庫(kù)的分頁(yè)
Oracle雖然不象Mysql有l(wèi)imit可用,十分方便,但也有自己的處理方法,它特殊的rownum對(duì)分頁(yè)有很重要的作
用。分頁(yè)可有很多種方法,其中最常用的是用minus。
如要顯示n1-n2記錄可寫(xiě)為:
(1)SELECT * FROM tablename WHERE rownum 注意:該語(yǔ)句不能使用order by,否則報(bào)錯(cuò)。
(2)把指針下移的辦法如:
其中:$page是當(dāng)前頁(yè);$pagesize是每頁(yè)顯示的記錄數(shù)
for($i=0;$i{
@ocifetch($stmt);
}
然后再用ocifetch($stmt)取出的數(shù)據(jù)就是你要顯示的記錄了
(3)對(duì)于有復(fù)雜查詢語(yǔ)句并用order by來(lái)排序的,可使用下面方法解決:
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游標(biāo)之類的東東,不太適合PHP使用。
四、特殊字符的插入處理
對(duì)于一些字符如單引號(hào)'在Oracle里是不能用addslashes處理的,但可以使用Oracle的CHR函數(shù)或再加個(gè)單引號(hào)
。
如: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的事務(wù)處理
OCIExecute()函數(shù):int OCIExecute ( int statement [, int mode] )
第二個(gè)參數(shù)mode共有兩個(gè):缺省為OCI_COMMIT_ON_SUCCESS,可省略。OCI_DEFAULT 表示用事務(wù)(Transation)
提交,不自動(dòng)提交。
如果你在程序中如果有兩個(gè)操作數(shù)據(jù)庫(kù)的語(yǔ)句需要同時(shí)成功執(zhí)行,有一個(gè)失敗就要rollback的話,可這樣寫(xiě):
$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類型的數(shù)據(jù)(含圖片的存儲(chǔ)與顯示處理)
對(duì)PHP程序員來(lái)講,Oracle最令人頭痛的莫過(guò)于使用LOB來(lái)處理圖片了。
1。PHP操作BLOB:
先建立一個(gè)表用于保存圖片。用戶上傳的圖片文件存放到BLOB中
CREATE TABLE PICTURES (
ID NUMBER,
IMGTYPE, VARCHAR2(60),
DESCRIPTION VARCHAR2(100),
PICTURE BLOB
);
如果要實(shí)現(xiàn)ID的自動(dòng)增加,再建一個(gè)SEQUENCE:
CREATE SEQUENCE PIC_SEQ;
PHP程序-插入部分:
$conn=OCILogon($username,$password,$sid);
//在這里要注意的兩點(diǎn):一是用EMPTY_BLOB()函數(shù)。這是Oracle的內(nèi)部函
//數(shù),返回一個(gè)LOB的定位符。在插入LOB時(shí),只能用這個(gè)辦法先生成一個(gè)
//空的LOB定位符,然后對(duì)這個(gè)定位符進(jìn)行操作。EMPTY_BLOB()函數(shù)是針
//對(duì)BLOB類型的,對(duì)應(yīng)于CLOB的是EMPTY_CLOB()。二是RETURNING后面的
//部分,把picture返回,讓PHP的OCI函數(shù)能夠處理。
$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");
//生成一個(gè)本地LOB對(duì)象的描述符。注意函數(shù)的第二個(gè)參數(shù):OCI_D_LOB,
//表示生成一個(gè)LOB對(duì)象。其它可能的還有OCI_D_FILE和OCI_D_ROWID,分
//別對(duì)應(yīng)于BFILE和ROWID對(duì)象。
$lob = OCINewDescriptor($conn, OCI_D_LOB);
//將生成的LOB對(duì)象綁定到前面SQL語(yǔ)句返回的定位符上。
OCIBindByName($stmt, ':PICTURE', &$lob, -1, OCI_B_BLOB);
OCIExecute($stmt);
//方法一:向LOB對(duì)象中存入數(shù)據(jù)。因?yàn)檫@里的源數(shù)據(jù)是一個(gè)文件,所以直接用LOB對(duì)象的savefile()方法。LOB
對(duì)象的其它方法還有:save()和load(),分別用來(lái)保存和取出數(shù)據(jù)。但BFILE類型只有一個(gè)方法就是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對(duì)象
OCIFreeDesc($lob);
OCIFreeStatement($stmt);
OCILogoff($conn);
?>
小技巧:在sqlplus里可用select dbms_lob.getlength(picture) from pictures;查看文件是否已存入到數(shù)據(jù)
庫(kù)或在PHP程序里用strlen()函數(shù)查看。
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()) 查看圖片的大小以確定圖片是否正確存入到數(shù)據(jù)庫(kù)。
?>
在需要顯示圖片的地方只要:

就能顯示圖片了
有的網(wǎng)上文章寫(xiě)用返回LOB值而非描述符的方法顯示,我沒(méi)有試成功,大家可以試下
代碼如下:
if (OCIFetchInto($stmt, $result, OCI_ASSOC+OCI_RETURN_LOBS))
{
echo "Content-type: " . StripSlashes($result[imgtype]);
echo StripSlashes($result[picture]);
}
2。PHP操作CLOB:
Oracle有一種數(shù)據(jù)類型叫VARCHAR2,用來(lái)表示不定長(zhǎng)的字符串。VARCHAR2也是Oracle公司推薦使用的類型。但
使用VARCHAR2有個(gè)問(wèn)題:最大只能表示4000個(gè)字符,也就相當(dāng)于2000個(gè)漢字。如果你的程序中某個(gè)字符串的長(zhǎng)
度要大于2000個(gè)漢字,用VARCHAR2就不能滿足要求了。這時(shí)候,你可以嘗試使用CLOB。CLOB和BLOB的最大長(zhǎng)度
是4GB。
下面是示例(參考了PHP英文版的手冊(cè)):
//要保存的文字
$clobtext="different dr2";
//db connection
$conn = OCIlogon("user","pw","TNS");
//這里原例子使用了一個(gè)存儲(chǔ)過(guò)程,你也可以用上面操作BLOB的方法來(lái)實(shí)現(xiàn)。
//如:$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);
?>

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

To safely and thoroughly uninstall MySQL and clean all residual files, follow the following steps: 1. Stop MySQL service; 2. Uninstall MySQL packages; 3. Clean configuration files and data directories; 4. Verify that the uninstallation is thorough.

Oracle is not only a database company, but also a leader in cloud computing and ERP systems. 1. Oracle provides comprehensive solutions from database to cloud services and ERP systems. 2. OracleCloud challenges AWS and Azure, providing IaaS, PaaS and SaaS services. 3. Oracle's ERP systems such as E-BusinessSuite and FusionApplications help enterprises optimize operations.

MongoDB is suitable for unstructured data and high scalability requirements, while Oracle is suitable for scenarios that require strict data consistency. 1.MongoDB flexibly stores data in different structures, suitable for social media and the Internet of Things. 2. Oracle structured data model ensures data integrity and is suitable for financial transactions. 3.MongoDB scales horizontally through shards, and Oracle scales vertically through RAC. 4.MongoDB has low maintenance costs, while Oracle has high maintenance costs but is fully supported.

Abstract of the first paragraph of the article: When choosing software to develop Yi framework applications, multiple factors need to be considered. While native mobile application development tools such as XCode and Android Studio can provide strong control and flexibility, cross-platform frameworks such as React Native and Flutter are becoming increasingly popular with the benefits of being able to deploy to multiple platforms at once. For developers new to mobile development, low-code or no-code platforms such as AppSheet and Glide can quickly and easily build applications. Additionally, cloud service providers such as AWS Amplify and Firebase provide comprehensive tools

The main difference between MySQL and Oracle is licenses, features, and advantages. 1. License: MySQL provides a GPL license for free use, and Oracle adopts a proprietary license, which is expensive. 2. Function: MySQL has simple functions and is suitable for web applications and small and medium-sized enterprises. Oracle has powerful functions and is suitable for large-scale data and complex businesses. 3. Advantages: MySQL is open source free, suitable for startups, and Oracle is reliable in performance, suitable for large enterprises.

The difference between MySQL and Oracle in performance and scalability is: 1. MySQL performs better on small to medium-sized data sets, suitable for fast scaling and efficient reading and writing; 2. Oracle has more advantages in handling large data sets and complex queries, suitable for high availability and complex business logic. MySQL extends through master-slave replication and sharding technologies, while Oracle achieves high availability and scalability through RAC.

MySQL uses GPL and commercial licenses for small and open source projects; Oracle uses commercial licenses for enterprises that require high performance. MySQL's GPL license is free, and commercial licenses require payment; Oracle license fees are calculated based on processors or users, and the cost is relatively high.

The key to learning Java without taking detours is: 1. Understand core concepts and grammar; 2. Practice more; 3. Understand memory management and garbage collection; 4. Join online communities; 5. Read other people’s code; 6. Understand common libraries and frameworks; 7. Learn to deal with common mistakes; 8. Make a learning plan and proceed step by step. These methods can help you master Java programming efficiently.
