搜尋
首頁php教程php手册Php操作oracle数据库指南-本人原创,经验总结,不能不看

oracle|数据|数据库|原创

本人由于工作关系使用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 "

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执行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 "

";
echo "in=".$in."
";
echo "inout=".$inout."
";
echo "out=".$out."
";
?>

三、Oracle数据库的分页
Oracle虽然不象Mysql有limit可用,十分方便,但也有自己的处理方法,它特殊的rownum对分页有很重要的作

用。分页可有很多种方法,其中最常用的是用minus。
如要显示n1-n2记录可写为:
(1)SELECT * FROM tablename WHERE rownum 注意:该语句不能使用order by,否则报错。
(2)把指针下移的办法如:
其中:$page是当前页;$pagesize是每页显示的记录数
for($i=0;$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()) 查看图片的大小以确定图片是否正确存入到数据库。

?>

在需要显示图片的地方只要:
放在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);
?>



陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
什么是oracle asm什么是oracle asmApr 18, 2022 pm 04:16 PM

oracle asm指的是“自动存储管理”,是一种卷管理器,可自动管理磁盘组并提供有效的数据冗余功能;它是做为单独的Oracle实例实施和部署。asm的优势:1、配置简单、可最大化推动数据库合并的存储资源利用;2、支持BIGFILE文件等。

Oracle怎么查询端口号Oracle怎么查询端口号May 13, 2022 am 10:10 AM

在Oracle中,可利用lsnrctl命令查询端口号,该命令是Oracle的监听命令;在启动、关闭或重启oracle监听器之前可使用该命令检查oracle监听器的状态,语法为“lsnrctl status”,结果PORT后的内容就是端口号。

oracle全角怎么转半角oracle全角怎么转半角May 13, 2022 pm 03:21 PM

在oracle中,可以利用“TO_SINGLE_BYTE(String)”将全角转换为半角;“TO_SINGLE_BYTE”函数可以将参数中所有多字节字符都替换为等价的单字节字符,只有当数据库字符集同时包含多字节和单字节字符的时候有效。

oracle怎么删除sequenceoracle怎么删除sequenceMay 13, 2022 pm 03:35 PM

在oracle中,可以利用“drop sequence sequence名”来删除sequence;sequence是自动增加数字序列的意思,也就是序列号,序列号自动增加不能重置,因此需要利用drop sequence语句来删除序列。

oracle怎么查询数据类型oracle怎么查询数据类型May 13, 2022 pm 04:19 PM

在oracle中,可以利用“select ... From all_tab_columns where table_name=upper('表名') AND owner=upper('数据库登录用户名');”语句查询数据库表的数据类型。

oracle查询怎么不区分大小写oracle查询怎么不区分大小写May 10, 2022 pm 05:45 PM

方法:1、利用“LOWER(字段值)”将字段转为小写,或者利用“UPPER(字段值)”将字段转为大写;2、利用“REGEXP_LIKE(字符串,正则表达式,'i')”,当参数设置为“i”时,说明进行匹配不区分大小写。

Oracle怎么修改sessionOracle怎么修改sessionMay 13, 2022 pm 05:06 PM

方法:1、利用“alter system set sessions=修改后的数值 scope=spfile”语句修改session参数;2、修改参数之后利用“shutdown immediate – startup”语句重启服务器即可生效。

oracle怎么设置表空间只读oracle怎么设置表空间只读May 13, 2022 pm 03:44 PM

在oracle中,可以利用“alter tablespace 表空间名 read only”语句设置表空间为只读;alter tablespace语句用于修改表空间的数据,表空间处于只读状态时文件中的数据就不会发生变化,可以提高系统的效率。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前By尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境