php连接oracle10数据库 转载
本文转载自:http://blog.csdn.net/wzg199088/article/details/6678241
一、配置环境:
访问Oracle8以上的数据库需要用到Oracle8Call-Interface(OCI8)。这个扩展模块需要Oracle8的
客户端函数库,因此需要你要连接远程Oracle数据库的话,还要装上Oracle的客户端软件-可以到Oracle网站上免费下载
-http://www.oracle.com,这是许多初学者常常忽略的,因此如果看了这篇文章,就不要在论坛上再提“为什么我连接不上Oracle数
据库”之类的问题了。
(1)首先确认安装了Oracle8i客户端,然后用net8assistant(客户端软件提供)建立一个服务命名,注意服
务名是oracle数据库的sid,可查询initsid文件里的server_names得到。
(2)在php.ini中把 ;extension=php_oci8.dll前面的注释符号“;”去掉,使php能够加载支持oracle的模块
。并把php_oci8.dll拷贝到你的windows2000server安装目录下的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 SQLstatement.</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 minusSELECT * 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 atest'));
或 SQL>insert into table values('it's atest'));
显示:
it's a test.
五、PHP和Oracle的事务处理
OCIExecute()函数:intOCIExecute ( 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) frompictures;查看文件是否已存入到数据
库或在PHP程序里用strlen()函数查看。
PHP程序-显示部分(getpicture.php):
<?
$conn = OCILogon($username, $password, $sid);
$stmt = OCIParse($conn,"SELECT imgtype,picture FROM PICTURES WHEREID=$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="放在OracleLOB中的图片">
就能显示图片了
有的网上文章写用返回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);
?>
php连接oracle10数据库 转载的更多相关文章
- php连接oracle数据库转载
php连接oracle数据库及查询数据的方法 投稿:shichen2014 字体:[增加 减小] 类型:转载 时间:2014-12-29 这篇文章主要介绍了php连接oracle数据库及查询数据的方法 ...
- java远程连接access数据库
本文转载自http://www.voidcn.com/article/p-tlrtkqlp-k.html 1 rmijdbc远程连接access数据库 正常情况下,常用的数据库sql server, ...
- 转载:Java连接MySQL 数据库的正确操作流程
转载网址:http://www.bitscn.com/pdb/mysql/201005/186551.html 以下的文章主要介绍的是Java连接MySQL 数据库(以MySQL数据库为例 ...
- 转载:EntityFramework 6.0< Code First > 连接 Mysql数据库
转载自:http://blog.csdn.net/kmguo/article/details/19650299 网上有很多关于用EntityFrame来连接Mysql数据库的教程,可是很多并不靠谱,转 ...
- JAVA通过JDBC连接Oracle数据库详解【转载】
JAVA通过JDBC连接Oracle数据库详解 (2011-03-15 00:10:03) 转载▼http://blog.sina.com.cn/s/blog_61da86dd0100q27w.htm ...
- php 连接mysql数据库并显示数据 实例 转载
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...
- Entity Framework连接Mysql数据库并生成Model和DAL层
Entity Framework (EF,ADO.NET Entity Framework)是微软官方提供的.NET平台的ORM框架.相比于LINQ TO SQL,EF框架具有很明显的优势: EF框架 ...
- 让Entity Framework支持MySql数据库(转载)
转载地址:http://www.cnblogs.com/wintersun/archive/2010/12/12/1903861.html Entity Framework 4.0 也可以支持大名鼎鼎 ...
- EntityFramework 6.0< Code First > 连接 Mysql数据库(转)
http://blog.csdn.net/kmguo/article/details/19650299 网上有很多关于用EntityFrame来连接Mysql数据库的教程,可是很多并不靠谱,转载的太多 ...
随机推荐
- Yii2 CSRF
一.CSRF 即Cross-site request forgery跨站请求伪造,是指有人冒充你的身份进行一些恶意操作. 比如你登录了网站A,网站A在你的电脑设置了cookie用以标识身份和状态,然后 ...
- Npoi Web 项目中(XSSFWorkbook) 导出出现无法访问已关闭的流的解决方法
原本在CS项目中用的好好的在BS项目中既然提示我导出出现无法访问已关闭的流的解决方法 比较郁闷经过研究 终于解决了先将方法发出来 让遇到此问题的筒子们以作参考 //新建类 重写Npoi流方法 publ ...
- [转]Git介绍
Git是一个分布式的版本控制工具,本篇文章从介绍Git开始,重点在于介绍Git的基本命令和使用技巧,让你尝试使用Git的同时,体验到原来一个版 本控制工具可以对开发产生如此之多的影响,文章分为两部分, ...
- Python argparse
http://songpengfei.iteye.com/blog/1440158 https://docs.python.org/2/library/argparse.html http://sta ...
- openssl rsa 加解密
<h4>1.openssl进行rsa加密解密</h4>首先介绍下命令台下openssl工具的简单使用:生成一个密钥:<pre lang="c" esc ...
- 最新 Arduino 驱动 12接口/户外 LED显示屏/LED点阵屏/LED单元板
起因 现有的驱动LED显示屏的资料,比较好的只有这个.但是它驱动的是08接口的室内显示屏,而我要驱动的是12接口的户外显示屏.两种屏幕的区别在于户外屏幕点阵比较稀疏,而且二者的扫描方式,驱动方式都不太 ...
- C#实现CAD数据转shape或mdb
jojojojo2002 原文C#实现CAD数据转shape或mdb 本文所指的CAD数据为不带空间参考和扩展数据的数据.如果CAD带了空间参考或是扩展属性数据的话,就要采用图形和属性分离的方法转CA ...
- Yii连接多个数据库的方法
一.配置多数据库 大多数情况下,我们都会采用同一类型的数据库,只是为了缓解压力分成主从或分布式形式而已.声明你可以在 主配置文件 ( main.php ) 中里声明其它的数据库连接: <?p ...
- js画线
<body> <div id="main"> </div> <div id="fd" style="filt ...
- 多态.xml
pre{ line-height:1; color:#1e1e1e; background-color:#f0f0f0; font-size:16px;}.sysFunc{color:#627cf6; ...