oci_new_descriptor

(PHP 5、PHP 7、PHP 8、PECL OCI8 >= 1.1.0)

oci_new_descriptor初始化一个新的空 LOB 或 FILE 描述符

描述

oci_new_descriptor(资源 $connection, 整数 $type = OCI_DTYPE_LOB): ?OCILob

分配资源以保存描述符或 LOB 定位符。

参数

connection

一个 Oracle 连接标识符,由 oci_connect()oci_pconnect() 返回。

type

type 的有效值为:OCI_DTYPE_FILEOCI_DTYPE_LOBOCI_DTYPE_ROWID

返回值

如果成功,则返回一个新的 LOB 或 FILE 描述符,否则返回 null

示例

示例 #1 oci_new_descriptor() 示例

<?php
/* 此脚本设计为从 HTML 表单调用。
* 它预期 $user、$password、$table、$where 和 $commitsize
* 从表单中传递进来。然后脚本使用 ROWID 删除
* 选定的行,并在每组 $commitsize 行之后提交。(谨慎使用,没有回滚)
*/
$conn = oci_connect($user, $password);
$stmt = oci_parse($conn, "select rowid from $table $where");
$rowid = oci_new_descriptor($conn, OCI_D_ROWID);
oci_define_by_name($stmt, "ROWID", $rowid);
oci_execute($stmt);
while (
oci_fetch($stmt)) {
$nrows = oci_num_rows($stmt);
$delete = oci_parse($conn, "delete from $table where ROWID = :rid");
oci_bind_by_name($delete, ":rid", $rowid, -1, OCI_B_ROWID);
oci_execute($delete);
echo
"$nrows\n";
if ((
$nrows % $commitsize) == 0) {
oci_commit($conn);
}
}
$nrows = oci_num_rows($stmt);
echo
"$nrows 已删除...\n";
oci_free_statement($stmt);
oci_close($conn);
?>
<?php
/* 此脚本演示了文件上传到 LOB 列
* 用于此示例的表单字段如下所示
* <form action="upload.php" method="post" enctype="multipart/form-data">
* <input type="file" name="lob_upload" />
* ...
*/
if (!isset($lob_upload) || $lob_upload == 'none'){
?>
<form action="upload.php" method="post" enctype="multipart/form-data">
上传文件:<input type="file" name="lob_upload" /><br />
<input type="submit" value="上传" /> - <input type="reset" value="重置" />
</form>
<?php
} else {

// $lob_upload 包含上传文件的临时文件名

// 另请参见文件上传的功能部分,
// 如果你想使用安全的上传

$conn = oci_connect($user, $password);
$lob = oci_new_descriptor($conn, OCI_D_LOB);
$stmt = oci_parse($conn, "insert into $table (id, the_blob)
values(my_seq.NEXTVAL, EMPTY_BLOB()) returning the_blob into :the_blob"
);
oci_bind_by_name($stmt, ':the_blob', $lob, -1, OCI_B_BLOB);
oci_execute($stmt, OCI_DEFAULT);
if (
$lob->savefile($lob_upload)){
oci_commit($conn);
echo
"Blob 已成功上传\n";
}else{
echo
"无法上传 Blob\n";
}
$lob->free();
oci_free_statement($stmt);
oci_close($conn);
}
?>

示例 #2 oci_new_descriptor() 示例

<?php
/* 调用包含 CLOB 作为输入参数的 PL/SQL 存储过程
* 参数。
* PL/SQL 存储过程签名的示例如下:
*
* PROCEDURE save_data
* 参数名称 类型 输入/输出 默认值?
* ------------------------------ ----------------------- ------ --------
* KEY NUMBER(38) IN
* DATA CLOB IN
*
*/

$conn = oci_connect($user, $password);
$stmt = oci_parse($conn, "begin save_data(:key, :data); end;");
$clob = oci_new_descriptor($conn, OCI_D_LOB);
oci_bind_by_name($stmt, ':key', $key);
oci_bind_by_name($stmt, ':data', $clob, -1, OCI_B_CLOB);
$clob->write($data);
oci_execute($stmt, OCI_DEFAULT);
oci_commit($conn);
$clob->free();
oci_free_statement($stmt);
?>

另请参阅

添加注释

用户贡献注释 14 个注释

<Serg Petrenko> pserg at inkfrog dot com
19 年前
如何将大型 XML 数据作为 CLOB 插入到带有 XMLType 字段的表中。

<?php

//CREATE TABLE sometable(
//id number(8) not null,
//record XMLType
//) XMLTYPE COLUMN record STORE AS OBJECT RELATIONAL
//XMLSCHEMA "someschema" ELEMENT "some_element";
//

$sql = "INSERT INTO sometable(id, record) VALUES(some_sequqnce.nextval, sys.xmltype.createxml(:rec)) RETURNING ID INTO :rid";
$stmt = OCIParse($ora_conn,$sql);
$clob = OCINewDescriptor($ora_conn, OCI_D_LOB);
$rowid = OCINewDescriptor($ora_conn,OCI_D_ROWID);
OCIBindByName($stmt, ':rec', &$clob, -1,OCI_B_CLOB);
OCIBindByName($stmt, ':rid', $rowid, -1);
$clob->WriteTemporary($xml,OCI_TEMP_CLOB);
$success = OCIExecute($stmt,OCI_DEFAULT);
if(!
$success) {
OCICommit($ora_conn);
}
OCIFreeStatement($stmt);
OCIFreeDesc($lob);

?>

希望对您有所帮助 :)
kirt at diagonalsoftware dot com
19 年前
以下是如何从存储过程中检索 CLOB 作为输出参数的示例。这有点笨拙,可能存在更简洁的方法,但我找不到。以下方法在 Oracle 9 中肯定有效

// 用于调用过程的查询,包括声明输出参数并将结果分配给要绑定的变量。
// 输出参数并将结果分配给要绑定的变量。
$qry = '
declare clob_out clob;
begin
myprocedure(someparam_in, clob_out);
:myclob := clob_out;
end;
';

// 解析查询并绑定“myclob”变量
$sth = OCIParse($conn,$qry);
$myclob = OCINewDescriptor($conn,OCI_D_LOB);
OCIBindByName($sth,":myclob",$myclob,-1,OCI_B_CLOB);

OCIExecute($sth);

// 显示结果
echo $myclob->load();
Maxwell_Smart (at) ThePentagon (dot) com
20 年前
只是一个说明。在 INSERT CLOB 时,如果使用 VALUES 子句,Oracle 会注意到:您不能使用除空或空以外的值来初始化对象中的内部 LOB 属性。也就是说,您不能使用文字。

这就是为什么这里的所有示例都插入 EMPTY_CLOB() 并使用 RETURNING 来获取指针。

但是,CLOB 也可以通过 SELECT 语句插入,并且不需要任何描述符。

示例

$Clob = Str_Replace("'", "''", $Clob);

OCIParse($DB, "INSERT INTO My_Table (My_Clob) SELECT '$Clob' FROM Dual");

当然,这允许使用 WHERE 子句。
moom_mong at yahoo dot com
22 年前
读取 lob 的另一种方式

$sql = OCIParse("select * from table_with_lob_field");
OCIExecute($sql, OCI_DEFAULT);
while ( OCIFetch($sql)) {
$o = ociresult($sql,"loc_field_name");
$loc_field_name = $o->load();
print $loc_field_name;
};
Nathan Rogers
20 年前
我找到了另一种插入/更新 lob 数据的方法。它的工作方式与将 lob 参数传递给存储过程相同,并且避免了对 RETURNING 子句的需求。
$lob = OCINewDescriptor($conn, OCI_D_LOB);
$stmt = OCIParse($conn,"insert into $table (id, the_blob)
values(my_seq.NEXTVAL, :the_blob)");
OCIBindByName($stmt, ':the_blob', &$lob, -1, OCI_B_BLOB);
$lob->WriteTemporary($data);
OCIExecute($stmt, OCI_DEFAULT);
$lob->close();
$lob->free();
OCICommit($conn);

在涉及触发器的某些情况下,您无法使用 RETURNING 子句,因此此方法会派上用场。我需要它的情况是更新具有 instead-of 更新触发器的视图。
jcd at iddg dot com
24 年前
[编辑说明:在 PHP 5 中,不要在绑定调用中为参数使用“&”]

上面的代码在某种程度上是正确的...以下是我如何让 CLOB 工作的示例

<?php
function insert_adinfo($AdInfoID, $MagazineType, $Publish, $DatePost, $BodyText)
{
global
$db;

// 将记录插入数据库
$clob = OCINewDescriptor($db, OCI_D_LOB);
$stmt = OCIParse($db,"insert into tblAdInfo values ($AdInfoID, $MagazineType, '$Publish', to_date('$DatePost', 'YYYY-MM-DD'), EMPTY_CLOB()) returning BodyText into :the_blob");
OCIBindByName($stmt, ':the_blob', &$clob, -1, OCI_B_CLOB);
OCIExecute($stmt, OCI_DEFAULT);
if(
$clob->save($BodyText)){
OCICommit($db);
}else{
echo
"Problems: Couldn't upload Clob\n";
}

OCIFreeDescriptor($clob);
OCIFreeStatement($stmt);
}
?>
aidanpeiser at yahoo dot com
22 年前
另一种显示您的 clob 详细信息的方式!

$query = "select * from Your_clob_table";
$stmt = OCIParse($conn, $query);
ociexecute($stmt);

while ( OCIFetch($stmt))
{
$lob = OCIResult($stmt,"CLOB_MESSAGE");
$CLOB_MESSAGE = $lob->load();
echo $CLOB_MESSAGE;
}

这有效,
cyrill@_malevanov_dot_spb_dot_ru
20 年前
将 CLOB 传递给存储过程并检索 CLOB(函数 lobinout(a in clob) return clob)

<?
error_reporting(1+2+4+8);
$conn = OCILogon('batdtd', 'batdtd', 'batxml');

$lobin = OCINewDescriptor($conn, OCI_D_LOB);
$lobout = OCINewDescriptor($conn, OCI_D_LOB);

$stmt = OCIParse($conn, "declare rs clob; begin :rs := lobinout(:par); end;");
$lob_data = 'abcdefgh';

echo "绑定 lobin...";
OCIBindByName($stmt, ':par', $lobin, -1, OCI_B_CLOB);

echo "完成<br>绑定 rs...";

OCIBindByName($stmt, ':rs', $lobout, -1, OCI_B_CLOB);

echo "完成<br>写入临时 lob...";
// 这里我们将数据传递给函数
$lobin -> WriteTemporary($lob_data);
echo "完成<br>执行...";

OCIExecute($stmt, OCI_DEFAULT);
// 这里我们加载从函数返回的数据
echo "完成<br>rs = ".$lobout->load();
OCICommit($conn);
$lobin -> free();
$lobout -> free();
OCIFreeStatement($stmt);
OCILogoff($conn);
?>
cjbj at hotmail dot com
20 年前
在 PHP5 中,示例 2 将 CLOB 绑定变量作为输入
参数传递给 PL/SQL 过程可以扩展到 BLOB。

关键变化是

OCIBindByName($stmt, ':data', $blob, -1, OCI_B_BLOB);
$blob->WriteTemporary($data, OCI_B_BLOB);

这对我来说在 PHP4 中不起作用。我相信这是因为
OCIWriteTemporaryLob() 的实现始终绑定为 CLOB。
(此信息截至 php4-STABLE-200403170230 为止)。在 PHP5 中,接口
已更改,并允许类型参数。
tca at engineer dot com
21 年前
从数据库中检索 CLOB 的两个示例。它们几乎完全相同。第一个使用包(和游标),这是我在工作中与 Oracle 交互的方式,第二个使用直接 SQL,大多数人都会在示例中发布它。

我还将大小写从大写转换为小写,因为这是我更喜欢使用关联数组的方式……

您可以使用 OCIColumnType() 函数而不是 get_class() 函数,它(在本例中)将返回“CLOB”作为结果……

/**
* 示例 1
*
* 使用 PL/SQL 包和游标
*
*/
$cursor=':p_cur';
$sql2="begin clobPackage.getClob($cursor); end;";
$curs=OCINewCursor($conn);
$stmt=OCIParse($conn,$sql2);
OCIBindByName($stmt,$cursor,&$curs,-1,OCI_B_CURSOR);
OCIExecute($stmt,OCI_DEFAULT);
OCIExecute($curs,OCI_DEFAULT);
$x=0;
while(OCIFetch($curs)){
$cols=OCINumCols($curs);
for($i=1;$i<=$cols;$i++){
$column_name=OCIColumnName($curs,$i);
if(is_object($tmp=OCIResult($curs,$i))&&get_class($tmp)=='OCI-Lob'){
$column_value=$tmp->load();
}else{
$column_value=$tmp;
}
$result[$x][strtolower($column_name)]=trim($column_value);
}
$x++;
}
OCICommit($conn);

/**
* 示例 2
*
* 使用 SELECT
*
*/
$query="SELECT a_num, a_clob FROM clob_test";
$stmt=OCIParse($conn,$query);
OCIExecute($stmt,OCI_DEFAULT);
$x=0;
while(OCIFetch($stmt)){
$ncols=OCINumCols($stmt);
for($i=1;$i<=$ncols;$i++){
$column_name=OCIColumnName($stmt,$i);
if(is_object($tmp=OCIResult($curs,$i))&&get_class($tmp)=='OCI-Lob'){
$column_value=$tmp->load();
}else{
$column_value=$tmp;
}
$result[$x][strtolower($column_name)]=trim($column_value);
}
$x++;
}
OCICommit($conn);

我希望有人发现这有用。

干杯,
凯斯。
Mike
12 年前
如果您将 clob 变量传递给 Oracle 存储过程,您可以

<?php
$qry
= 'begin my_sp(:largetext); end;';
$stmt = oci_parse($conn, $qry); //此处未包含 $conn 的定义
$clob = oci_new_descriptor($conn, OCI_D_LOB);
oci_bind_by_name($stmt, ":largetext", $clob, -1, OCI_B_CLOB);
$clob->writetemporary($mylargedata);
oci_execute($stmt);
$clob->free();
oci_free_statement($stmt);
?>

希望这有帮助!
ajitsingh4u at gmail dot com
16 年前
<?php
// 调用存储过程获取 clob 数据类型(我们用于从 Oracle 获取 xml)

error_reporting(E_ALL ^ E_NOTICE);

$conn = oci_connect($user, $password);

$sql = "BEGIN sp_employee_xml_data_select(:result); END;";
$stmt = oci_parse($conn , $sql);

$objClob = oci_new_descriptor($conn, OCI_D_LOB);
oci_bind_by_name($stmt, ':result', $objClob, -1, OCI_B_CLOB);

oci_execute($stmt, OCI_DEFAULT);
$xmlData = $objClob->load($result);

$objClob->free();
oci_free_statement($stmt);

echo
$xmlData;

?>
sozturk at emediamillworks dot com
22 年前
我遇到了与上面其中一个注释中所述的相同问题,即使用更短的内容更新 lob。在替换文本末尾添加“\0”也没有帮助。但以下代码运行得很好

$sql = "UPDATE sometable SET lob_col = EMPTY_LOB() WHERE key_col = $key RETURNING lob_col INTO :lob";
$stmt = OCIParse($conn,$sql);
$lob = OCINewDescriptor($conn,OCI_D_LOB);
OCIBindByName($stmt,':lob',&$lob,-1,OCI_B_BLOB);
OCIExecute($stmt,OCI_DEFAULT);
$lob->save($sometext);
$lob->free();
Ben Hubbard ben at vonik dot com
18 年前
以下是另一个将 BLOB 插入表中使用 PL/SQL 函数的示例。

Oracle 数据库代码

create table blob_table ( the_blob blob);

create or replace function insert_blob(out_blob out blob)
return integer is
begin
insert into blob_table values (EMPTY_BLOB())
return the_blob into out_blob;
return 0; /* 成功 */
end insert_blob;

PHP 代码

<?php
$iResult
= -1;
$strTestData = '测试 123';
$conn = oci_connect($user, $password);
$stmt = oci_parse($conn, "begin :RES := insert_blob(:OUT_BLOB); end;");

$objBlob = oci_new_descriptor($conn, OCI_D_LOB);
oci_bind_by_name($stmt, ":RES", $iResult);
oci_bind_by_name($stmt, ":OUT_BLOB", $objBlob, -1, OCI_B_BLOB);
oci_execute($stmt, OCI_DEFAULT);
$objBlob->write($strTestData);
oci_commit($conn);
$objBlob->free();
oci_free_statement($stmt);
?>
To Top