Pro * Cクエリで変数式のリストを指定するには?
-
20-09-2019 - |
質問
私は最適化しようとしているのPro * Cのクエリに問題があります。
巨大なデータベース内の行のために、我々のアプリケーションの検索を説明するために。これらの行は、複数の言語で存在し、古いコードは、アレイ内の各言語の行を選択しました。これらのクエリは、我々のアプリの中で最も時間のかかる部分であるとして、今、私は、配列に直接書き込みを行う唯一のクエリを作りたかっます。
言語コードは2文字のISO-639コード(EN英語、FRフランス語の場合)である。
古い方法(これは意思を表示するための唯一の単純化されたコードである)
struct ROW arr[MAX_LAN];
struct ROW_IND arr_ind[MAX_LAN];
uint_t LanIdx;
for(LanIdx=0; LanIdx<MAX_LAN; LanIdx++) {
EXEC SQL SELECT * /* Don't look at the *, it's for obfuscation only */
INTO :arr[LanIdx]:arr_ind[LanIdx]
FROM table WHERE id=:uniqid AND language=:LanCode[LanIdx];
}
私はこのような何かをしたいと思います:
EXEC SQL SELECT * /* Don't look at the *, it's for obfuscation only */
INTO :arr:arr_ind
FROM table WHERE id=:uniqid AND language IN (:LanCodes);
私はLanCodesを定義すべきかわからない。
これは、このような定数(コンパイル時)のリストで動作します。
EXEC SQL SELECT * /* Don't look at the *, it's for obfuscation only */
INTO :arr:arr_ind
FROM table WHERE id=:uniqid AND language IN ('en','fr','de');
言語は、場合に変化することができるように、これは、有用ではない。
私のような何かを書く場合は、
char LanCodes[MAX_LANS*5];
sprintf(LanCodes, "%s", LanCode[LanIdx]);
EXEC SQL SELECT * /* Don't look at the *, it's for obfuscation only */
INTO :arr:arr_ind
FROM table WHERE id=:uniqid AND language IN (:LanCodes);
これは、1つの言語コードが文字列である場合にのみ機能します。
だから私の質問は、誰もがこの仕事を作る方法を知っているんですか? Oracleのドキュメントは非常に大きいですが、私はを見てどこか分かりません。私はさまざまな方法を試してみましたが、どれも働いた。
編集 [OK]を、私は働く解決策を見つけました。それは進んでいないのです、エレガントではないのですが、それはうまく動作します。私は私のクエリでOR句のリストを入れて、それは私が必要とする形式で必要なものを返します。
EXEC SQL SELECT * /* Don't look at the *, it's for obfuscation only */
INTO :arr:arr_ind
FROM table WHERE id=:uniqid AND (
language=:v1[ 0] OR
language=:v1[ 1] OR
language=:v1[ 2] OR
language=:v1[ 3] OR
language=:v1[ 4] OR
language=:v1[ 5] OR
language=:v1[ 6] OR
language=:v1[ 7] OR
language=:v1[ 8] OR
language=:v1[ 9] OR
language=:v1[10] OR
language=:v1[11] OR
language=:v1[12] OR
language=:v1[13] OR
language=:v1[14] OR
language=:v1[15] OR
language=:v1[16] OR
language=:v1[17] OR
language=:v1[18] OR
language=:v1[19] OR
language=:v1[20] OR
language=:v1[21] OR
language=:v1[22] OR
language=:v1[23] OR
language=:v1[24] OR
language=:v1[25] OR
language=:v1[26] OR
language=:v1[27] OR
language=:v1[28] OR
language=:v1[29] OR
language=:v1[30]);
2つの以上の言語がある場合、それは高速ですので、私は、この変異体またはフェッチする言語の数に応じて、古いものを呼び出します。
解決
おそらくこの AskTom記事にはあなたを助けることができます。
他のヒント
あなたはせずにこれを行うことはできませんOracle動的SQL を。あなたは、実行時に、あなたのIN句を構築し、IMMEDIATEを実行する必要があります。少なくとも、あなたはあなたのクエリに基づいて方法1を使用することができます。
私は前IDと行が「中」リストにおける可能な値の順列である行の集合からなるテーブルを使用しています。それから私は、に基づいて、テーブルへの結合します IDとそれは私が必要とする結果が得られます。
create table permute (
id number,
lang char(2)
);
create index permute_p1 on permute ( lang, id );
insert into permute ( id, lang ) values ( 1, 'en' );
insert into permute ( id, lang ) values ( 2, 'en' );
insert into permute ( id, lang ) values ( 2, 'fr' );
...
あなたがしなければならないすべては正しい「ID」値2、3、4を選ぶ...とにそれを入れています 参加。
... 主な文字列:= 'SELECT * FROMテーブルWHERE ID =:uniqidと言語の'; - accomadateするために、2つに分割することができますuniqd ... v_stringにLANGUAGE_CODEを選択 x_tableから。 ループ コピー&、連結方式はLanCode_Stringにして、「」とv_string。 ループを終了します。 。.. 主な文字列へのconcat Lancode。 。.. 主な文字列を準備して実行します。