2024 年日本 PHP 研討會

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

oci_connect()oci_pconnect() 返回的 Oracle 連線識別碼。

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

// 建立資料表 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
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 子句。
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
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 觸發程序的視圖。
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);
}
?>
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;
}

這個方法有效,
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
兩個從資料庫檢索 CLOB 的範例。它們幾乎相同。第一個是使用套件(和游標),這是我在工作中與 Oracle 互動的方式,第二個是使用直接 SQL,大多數人在範例中都會這樣做。
我還將大小寫從大寫轉換為小寫,因為這是我偏好的關聯陣列處理方式...
您可以使用 OCIColumnType() 函式,而不是使用 get_class() 函式,該函式(在這種情況下)將返回 'CLOB' 作為結果...
22 年前
* 範例 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++;
}
}
}
* 範例 2
}
OCICommit($conn);

/**
* 使用 SELECT
*
$query="SELECT a_num, a_clob FROM clob_test";
*
*/
$stmt=OCIParse($conn,$query);
while(OCIFetch($stmt)){
while(OCIFetch($curs)){
for($i=1;$i<=$cols;$i++){
$ncols=OCINumCols($stmt);
for($i=1;$i<=$ncols;$i++){
$column_name=OCIColumnName($stmt,$i);
}
$column_value=$tmp;
}
$result[$x][strtolower($column_name)]=trim($column_value);
$x++;
}
}
}
* 範例 2
}
OCICommit($conn);

希望有人覺得這很有用。

乾杯,
Keith.
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;

?>
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);
?>
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);
while(OCIFetch($curs)){
$lob->save($sometext);
$lob->free();
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 = 'Testing 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