PHP Conference Japan 2024

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 个注释

3
<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);

?>

希望它能有所帮助 :)
1
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();
1
Maxwell_Smart (at) ThePentagon (dot) com
21 年前
只是一个说明。在插入 CLOB 时,如果使用 VALUES 子句,Oracle 指出:您不能使用除空或 null 之外的值来初始化对象中的内部 LOB 属性。也就是说,您不能使用文字。

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

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

示例

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

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

当然,这也允许使用 WHERE 子句。
1
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;
};
2
Nathan Rogers
21 年前
我发现了另一种插入/更新 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 update 触发器的视图。
2
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
"问题:无法上传Clob\n";
}

OCIFreeDescriptor($clob);
OCIFreeStatement($stmt);
}
?>
1
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;
}

这有效,
1
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中,接口
已更改,并允许类型参数。
1
tca at engineer dot com
22 年前
从数据库中检索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);

我希望有人发现这有用。

干杯,
基思。
0
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);
?>

希望这有帮助!
0
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;

?>
0
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);
?>
0
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();
-1
Ben Hubbard ben at vonik dot com
18年前
以下是另一个使用PL/SQL函数将BLOB插入表的示例。

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