목차
ERROR - Could not parse SQL statement.
php教程 php手册 Php操作oracle数据库指南-本人原创,经验总结,不能不看

Php操作oracle数据库指南-本人原创,经验总结,不能不看

Jun 21, 2016 am 09:14 AM
oracle quot stmt

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으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Oracle의 테이블 스페이스 크기를 확인하는 방법 Oracle의 테이블 스페이스 크기를 확인하는 방법 Apr 11, 2025 pm 08:15 PM

Oracle 테이블 스페이스 크기를 쿼리하려면 다음 단계를 따르십시오. 쿼리를 실행하여 테이블 스페이스 이름을 결정하십시오. 쿼리를 실행하여 테이블 스페이스 크기를 쿼리하십시오. sum (bytes)을 total_size, sum (bytes_free)으로 sum (bytes_free), sum (bytes) - sum (bytes_free)으로 dba_data_fices where tablespace_.

Oracle 데이터베이스를 가져 오는 방법 Oracle 데이터베이스를 가져 오는 방법 Apr 11, 2025 pm 08:06 PM

데이터 가져 오기 방법 : 1. SQLLOADER 유틸리티 사용 : 데이터 파일 준비, 제어 파일 작성 및 SQLLOADER 실행; 2. IMP/EXP 도구를 사용하십시오 : 데이터 내보내기, 데이터 가져 오기. 팁 : 1. 빅 데이터 세트에 권장되는 SQL*로더; 2. 대상 테이블이 존재해야하고 열 정의가 일치해야합니다. 3. 가져 오기 후에는 데이터 무결성을 확인해야합니다.

Oracle에 테이블 필드를 추가하는 방법 Oracle에 테이블 필드를 추가하는 방법 Apr 11, 2025 pm 07:30 PM

Alter Table 문을 사용하십시오. 특정 구문은 다음과 같습니다. Alter Table_Name Add Column_name Data_Type [제한 조건 -Clause]. 여기서 : table_name은 테이블 이름, column_name은 필드 이름, data_type는 데이터 유형이며, 제한 조건은 선택적 제한 조건입니다. 예 : Alter Table 직원 이메일 추가 Varchar2 (100) 직원 테이블에 이메일 필드를 추가합니다.

Oracle에서 테이블을 만드는 방법 Oracle에서 테이블을 만드는 방법 Apr 11, 2025 pm 08:00 PM

Oracle 테이블 작성에는 다음 단계가 필요합니다. 테이블 작성 구문을 사용하여 테이블 이름, 열 이름, 데이터 유형, 제약 조건 및 기본값을 지정하십시오. 테이블 이름은 간결하고 설명 적이어야하며 30자를 초과해서는 안됩니다. 열 이름은 설명 적이어야하며 데이터 유형은 열에 저장된 데이터 유형을 지정합니다. NOT NULL 제약 조건은 열에서 NULL 값이 허용되지 않도록하고 기본 조항은 열의 기본값을 지정합니다. 테이블의 고유 한 레코드를 식별하기위한 주요 주요 제약. 외국 키 제약 조건은 테이블의 열이 다른 테이블의 기본 키를 지칭하도록 지정합니다. 기본 키, 고유 한 제약 조건 및 기본값이 포함 된 샘플 테이블 학생의 생성을 참조하십시오.

Oracle에서 Barbled 코드를 해결하는 방법 Oracle에서 Barbled 코드를 해결하는 방법 Apr 11, 2025 pm 10:09 PM

데이터베이스 문자 세트를 확인하여 데이터와 일치하는지 확인하여 Oracle Garbled 문제를 해결할 수 있습니다. 클라이언트 문자 세트를 데이터베이스와 일치하도록 설정하십시오. 데이터베이스 문자 세트와 일치하도록 데이터 변환 또는 열 문자 세트를 수정하십시오. 유니 코드 문자 세트를 사용하고 멀티 바이트 문자 세트를 피하십시오. 데이터베이스 및 클라이언트의 언어 설정이 올바른지 확인하십시오.

Oracle 설치를 제거하는 방법에 실패했습니다 Oracle 설치를 제거하는 방법에 실패했습니다 Apr 11, 2025 pm 08:24 PM

Oracle 설치 실패에 대한 방법 제거 : Oracle Service를 닫고 Oracle Program 파일 및 레지스트리 키 삭제, Oracle 환경 변수를 제거하고 컴퓨터를 다시 시작하십시오. 제거되지 않으면 Oracle 범용 제거 도구를 사용하여 수동으로 제거 할 수 있습니다.

Oracle을 수반하는 방법 Oracle을 수반하는 방법 Apr 11, 2025 pm 07:33 PM

Oracle은 여러 가지 중복 제거 쿼리 방법을 제공합니다. 별개의 키워드는 각 열에 고유 한 값을 반환합니다. 그룹 별 조항은 결과를 그룹화하고 각 그룹에 대해 비 반복 값을 반환합니다. 고유 한 키워드는 고유 한 행만 포함 된 인덱스를 만드는 데 사용되며 인덱스 쿼리는 자동으로 망상됩니다. row_number () 함수는 고유 한 숫자를 할당하고 1 행 만 포함하는 결과를 필터링합니다. 최소 () 또는 max () 함수는 숫자 열의 비 반복 값을 반환합니다. 교차 연산자는 두 결과 세트의 공통 값을 반환합니다 (중복 없음).

Oracle View를 암호화하는 방법 Oracle View를 암호화하는 방법 Apr 11, 2025 pm 08:30 PM

Oracle View 암호화를 사용하면보기에서 데이터를 암호화 할 수 있으므로 민감한 정보의 보안을 향상시킬 수 있습니다. 단계에는 다음이 포함됩니다. 1) 마스터 암호화 키 생성 (MEK); 2) 암호화 된 뷰 생성, 암호화 할보기 및 MEK를 지정하는 것; 3) 사용자가 암호화 된보기에 액세스하도록 승인합니다. 암호화 된 뷰 작동 방식 : 사용자가 암호화 된보기를 쿼리 할 때 Oracle은 MEK를 사용하여 데이터를 해독하여 공인 사용자 만 읽기 쉬운 데이터에 액세스 할 수 있도록합니다.

See all articles