IN
の値を渡すことはお勧めできません 文字列連結としての条件。もちろん、最初はセキュリティと正確さですが、次のポイントはパフォーマンスです。
ステートメントを呼び出すたびに、データベースエンジンはそれを解析し、クエリプランを作成し、その後SQLステートメントで指定されたアクションを実行します。
毎回クエリテキストを最初から作成し、3つのステージすべてを毎回実行します。
ただし、バインド変数を常に使用すると、クエリは同じように見えるため、データベースはキャッシュされたクエリプランを使用してクエリの実行を高速化します。 oci_parse()
を呼び出すこともできます 一度だけ、 $ stmt
を再利用します 提供されたパラメータのセットが異なる変数。
したがって、最高のパフォーマンスを得るには、バインド変数を使用し、 oci_bind_array_by_name
。
さらに、 oci_fetch_allを使用して結果を取得することもできます。コード>
結果セットを行ごとに読み取るよりも高速に実行される場合がありますが、結果を処理するロジックによって異なります。
更新
配列パラメータの受け渡しは、PL / SQLブロックを実行する場合にのみ機能し、SQL文では使用できないようです。ただし、別の可能性として、コレクション
を使用することもできます。 パラメータ値のリストを渡します。配列を使用しても質問の条件を満たすことは可能ですが、この方法はあまり洗練されていません。
データベースをクエリするさまざまな方法のほかに、システム設定などがあります。 PHPの場合、 php.ini
にいくつかのパラメーターがあります。 Oracleとの相互作用を制御するファイル。それらの1つ( oci8.statement_cache_size
)クエリのキャッシュとパフォーマンスに関連します。
例
すべての例で、Oracleの同じデータ設定を使用しています。
データを渡すために、事前定義された SYS.ODCIVarchar2List
を選択します。 タイプですが、同じ特性を持つカスタムタイプを定義することもできます(データセットアップの例で示されています)。以下は、データスキームのセットアップとDMLでのコレクションの使用の原則を説明するコードです。
create table myTable(value varchar2(100), key varchar2(100))
/
insert into myTable(value, key)
select * from (
select 'apple', 'apple_one' from dual union all
select 'apple', 'apple_two' from dual union all
select 'banana', 'banana_one' from dual union all
select 'orange', 'orange_one' from dual union all
select 'orange', 'orange_two' from dual union all
select 'potato', 'potato_one' from dual
)
/
create or replace type TCustomList as table of varchar2(4000)
/
create or replace package TestPackage as
type TKeyList is table of varchar2(1000) index by binary_integer;
function test_select(pKeyList in out TKeyList) return sys_refcursor;
end;
/
create or replace package body TestPackage is
function test_select(pKeyList in out TKeyList) return sys_refcursor
is
vParam sys.ODCIVarchar2List := sys.ODCIVarchar2List();
vCur sys_refcursor;
vIdx binary_integer;
begin
vIdx := pKeyList.first;
while(vIdx is not null) loop
vParam.Extend;
vParam(vParam.last) := pKeyList(vIdx);
vIdx := pKeyList.next(vIdx);
end loop;
open vCur for
select * from myTable where value in (select column_value from table(vParam))
;
return vCur;
end;
end;
/
コレクションを示すためのクエリ:
--select by value list
select * from myTable
where value in (
select column_value
from table(Sys.ODCIVarchar2List('banana','potato'))
)
/
--same with custom type
select * from myTable
where value in (
select column_value
from table(TCustomList('banana','potato'))
)
/
--same with demonstration of casting
select * from myTable
where value in (
select column_value
from table(cast(TCustomList('banana','potato') as Sys.ODCIVarchar2List))
)
/
例1-コレクションを使用したPHPからの呼び出し
<?php
$keyList = array('apple', 'potato');
$conn = oci_pconnect("user_name", "user_password", "SERVER_TNS_NAME");
$stmt = oci_parse($conn, "SELECT * FROM myTable where value in (select column_value from table(:key_list))");
$coll = oci_new_collection($conn, 'ODCIVARCHAR2LIST','SYS');
for ($i=0; $i < count($keyList); $i++) {
$coll->append($keyList[$i]);
}
oci_bind_by_name($stmt, 'key_list', $coll, -1, OCI_B_NTY);
oci_execute($stmt);
while($row = oci_fetch_array($stmt, OCI_ASSOC)) {
echo "{$row['KEY']}, {$row['VALUE']}\n"; // Print the values
}
echo "---\n";
$coll->free();
//-- Run statement another time with different parameters
//-- without reparsing.
$coll = oci_new_collection($conn, 'ODCIVARCHAR2LIST','SYS');
$coll->append('banana');
oci_bind_by_name($stmt, 'key_list', $coll, -1, OCI_B_NTY);
oci_execute($stmt);
while($row = oci_fetch_array($stmt, OCI_ASSOC)) {
echo "{$row['KEY']}, {$row['VALUE']}\n"; // Print the values
}
echo "---\n";
$coll->free();
oci_free_statement($stmt);
oci_close($conn);
?>
例2-配列とパッケージを使用してPHPから呼び出す
<?php
$keyList = array('apple', 'potato');
$conn = oci_pconnect("user_name", "user_password", "SERVER_TNS_NAME");
$stmt = oci_parse($conn, "begin :cur := TestPackage.test_select(:key_list); end;");
$curs = oci_new_cursor($conn);
oci_bind_array_by_name($stmt, "key_list", $keyList, 2, 100, SQLT_CHR);
oci_bind_by_name($stmt, "cur", $curs, -1, OCI_B_CURSOR);
oci_execute($stmt);
oci_execute($curs);
while($row = oci_fetch_array($curs, OCI_ASSOC)) {
echo "{$row['KEY']}, {$row['VALUE']}\n"; // Print the values
}
echo "---\n";
//-- Run statement another time with different parameters
//-- without reparsing.
$keyList = array('banana');
oci_bind_array_by_name($stmt, "key_list", $keyList, 2, 100, SQLT_CHR);
oci_execute($stmt);
oci_execute($curs);
while($row = oci_fetch_array($curs, OCI_ASSOC)) {
echo "{$row['KEY']}, {$row['VALUE']}\n"; // Print the values
}
echo "---\n";
oci_free_statement($stmt);
oci_close($conn);
?>
例3-配列と匿名ブロックを使用したPHPからの呼び出し
<?php
$keyList = array('apple', 'potato');
$conn = oci_pconnect("user_name", "user_password", "SERVER_TNS_NAME");
$stmt = oci_parse($conn, "
declare
type TKeyList is table of varchar2(4000) index by binary_integer;
pKeyList TKeyList := :key_list;
vParam sys.ODCIVarchar2List := sys.ODCIVarchar2List();
vIdx binary_integer;
begin
-- Copy PL/SQL array to a type which allowed in SQL context
vIdx := pKeyList.first;
while(vIdx is not null) loop
vParam.Extend;
vParam(vParam.last) := pKeyList(vIdx);
vIdx := pKeyList.next(vIdx);
end loop;
open :cur for select * from myTable where value in (select column_value from table(vParam));
end;
");
$curs = oci_new_cursor($conn);
oci_bind_array_by_name($stmt, "key_list", $keyList, 2, 100, SQLT_CHR);
oci_bind_by_name($stmt, "cur", $curs, -1, OCI_B_CURSOR);
oci_execute($stmt);
oci_execute($curs);
while($row = oci_fetch_array($curs, OCI_ASSOC)) {
echo "{$row['KEY']}, {$row['VALUE']}\n"; // Print the values
}
echo "---\n";
//-- Run statement another time with different parameters
//-- without reparsing.
$keyList = array('banana');
oci_bind_array_by_name($stmt, "key_list", $keyList, 2, 100, SQLT_CHR);
oci_execute($stmt);
oci_execute($curs);
while($row = oci_fetch_array($curs, OCI_ASSOC)) {
echo "{$row['KEY']}, {$row['VALUE']}\n"; // Print the values
}
echo "---\n";
oci_free_statement($stmt);
oci_close($conn);
?>