3

Pro*C コードを試しています。

私は 3 つのテーブルを持ってempmgrますall。3 つのテーブルすべてに と が含まれemp_idていemp_nameます。以下のコードを試してみましたが、エラーが発生しました。可能かどうか教えてください。

const char table_name[3]={'emp','mgr','all'}
int counter = 0;
while(counter < 3)
{
 . . .
 EXEC SQL SELECT emp_name INTO :ename 
      From :table_name[counter++] 
      where emp_id=:emp_id;
}

SELECTとに変数を使用できますFROMか?

4

2 に答える 2

3

これは動的 SQL と呼ばれます。

この情報を使用します。

動的 SQL

組み込み SQL は固定アプリケーションには問題ありませんが、プログラムが SQL ステートメント全体を動的に作成することが重要な場合があります。
動的 SQL では、ストリング変数に保管されたステートメントを発行できます。
PREPARE は文字列を SQL ステートメントに変換し、EXECUTE はそのステートメントを実行します。次の例を考えてみましょう。

   char *s = "INSERT INTO emp VALUES(1234, 'jon', 3)";
   EXEC SQL PREPARE q FROM :s;
   EXEC SQL EXECUTE q;

または、PREPARE と EXECUTE を 1 つのステートメントに結合することもできます。

   char *s = "INSERT INTO emp VALUES(1234, 'jon', 3)";
   EXEC SQL EXECUTE IMMEDIATE :s;

ソース: http://infolab.stanford.edu/~ullman/fcdb/oracle/or-proc.html

于 2012-09-28T10:00:47.563 に答える
2

いいえ、ホスト変数を使用してテーブル名を Pro*C の静的 SQL ステートメントに指定することはできません。

Oracle Pro*C Programmer's Guide for Oracle 11.2gを引用するには:

入力ホスト変数を使用して、SQL キーワードまたはデータベース オブジェクトの名前を指定することはできません。[..] 実行時にデータベース オブジェクト名を変更する必要がある場合は、動的 SQL を使用します。第13章「Oracle動的SQL」も参照してください。

Pro*C では、Oracle は SQL 文を実行するためのさまざまな方法を提供します。主な違いは、静的メソッドと動的メソッドです。動的には、さまざまな自由度を可能にするいくつかのサブメソッドがあります。

静的 SQL ステートメントは 100% 静的ではありません。入力/出力ホスト変数を where 句式で (オペランドとして) 使用して、insert ステートメントで値を指定したり、select ターゲットなどとして使用したりできます。ただし、テーブル名を指定することはできません。これは、静的組み込み SQL には「動的すぎる」ものです。

動的に準備された SQL ステートメントで引き続きホスト変数を使用できることに注意してください。これは、SQL インジェクションの問題を回避し、パフォーマンスを向上させるために推奨されます (ステートメントが複数回実行される場合)。

例 (Oracle 動的 SQL メソッド 3 を使用):

const char *table_name[3] = {"emp", "mgr", "all"};
unsigned table_name_size = 0;
unsigned i = 0;
for (i = 0; i<table_name_size; ++i) {
    char stmt[128] = {0};
    snprintf(stmt, 128,
        "SELECT emp_name "
        "  FROM %s " 
        "  WHERE "
        "    emp_id = :emp_id",
      table_name[i]);

    EXEC SQL PREPARE emp_stmt FROM :stmt;
    // check sqlca.sqlcode ...
    EXEC SQL DECLARE emp_cursor CURSOR FOR emp_stmt;
    EXEC SQL OPEN emp_cursor USING :emp_id;
    // check sqlca.sqlcode ...
    EXEC SQL FETCH emp_cursor INTO :ename;
    // check sqlca.sqlcode ...
    EXEC SQL CLOSE emp_cursor;
    // check sqlca.sqlcode ...

    // ...
}
于 2013-08-11T10:46:15.207 に答える