2011-10-26 11 views
3

PL/SQLの新機能です。私はこの言語でループに問題があります。私はこのようなループを作りたいです:PL/SQLのループおよび列の場合

FOR nr IN 1..102 
LOOP 
    DBMS_OUTPUT.PUT_LINE(nr); 
    IF rec.column_||nr IS NULL 
    THEN 
    DBMS_OUTPUT.PUT_LINE('test'); 
    END IF; 
END LOOP; 

私はカーソルを作成しました。ご覧のとおり、column_1からcolumn_102までの名前のカラムを持つすべてのカラムをチェックしたいと思います。残念ながら||オペレータはこの状況では動作しません。 私の問題の解決策をご存知ですか?

答えて

5

dynamic PL/SQLでこれを行うことができます。 EXECUTE IMMEDIATEステートメントを使用して文字列引数をPL/SQLとして実行します。これは、質問で意図したとおりに||で補うことができます。

例:

BEGIN 
    FOR nr IN 1..102 
    LOOP 
     DBMS_OUTPUT.PUT_LINE(nr); 
     EXECUTE IMMEDIATE 
      'BEGIN ' || 
      'IF rec.column.' || nr ||' is null THEN ' || 
       'DBMS_OUTPUT.PUT_LINE(''test''); ' || 
      'END IF; ' || 
      'END; '; 
    END LOOP; 
END; 

それとも、また変数にrec.column.' || nr ||' is nullを割り当て、EXECUTE IMMEDIATE部外PUT_LINEを作ることができる:

UPDATEBOOLEAN変数をバインドすることはできないようです、この例ではNUMBERを使用するように変更しました。

UPDATE 2:この場合、効率が改善される可能性があります。動的SQLには定数VARCHARを使用し、バインドされた変数でnrを渡します。これは、大きなループの場合にネイティブSQLを使用するよりも効率的です。私は'rec.column.:arg is nullが​​として実行されるとは思わない。

DECLARE 
    isnull NUMBER; 
BEGIN 
    FOR nr IN 1..102 
    LOOP 
     DBMS_OUTPUT.PUT_LINE(nr); 
     EXECUTE IMMEDIATE 
      'BEGIN ' || 
       'IF rec.column.' || nr ||' IS NULL THEN ' || 
        ':x:=1; ' || 
       'ELSE ' || 
        ':x:=0; ' || 
       'END IF; ' || 
      'END; ' 
      USING OUT isnull; 
     IF isnull = 1 THEN 
      DBMS_OUTPUT.PUT_LINE('test'); 
     END IF; 
    END LOOP; 
END; 

UPDATE 3: ことを見て:それは(スコープ外)定義されていないので、動的SQLステートメント内recにアクセスすることはできません

  • 動的ステートメントへの引数として非SQL型を渡すことはできないようです(r ECORD、カーソル)

可能な回避策は、動的ステートメントにいくつかのid列(SQL型)に結合し、そして現在の列がnullであるかどうかを調べるためにselect句を使用することです:

DECLARE 
     isnull NUMBER; 
     rec_id NUMBER; -- Identifier of the fetched record 
    BEGIN 
     rec_id := rec.id; 
     FOR nr IN 1..102 
     LOOP 
      DBMS_OUTPUT.PUT_LINE(nr); 
      EXECUTE IMMEDIATE 
       'SELECT 1 FROM my_table WHERE id = :idarg ' || 
        ' AND column_' || nr || ' IS NULL' 
       INTO isnull USING rec_id; 
      IF isnull = 1 THEN 
       DBMS_OUTPUT.PUT_LINE('test'); 
      END IF; 
     END LOOP; 
    END;
+0

あなたは私に例を教えていただけますか? – matyyyy

+0

残念ながらBOOLEANはSQL型ではありません。そのためにエラーが発生します。 – matyyyy

+0

是非、ここで説明した通りです(http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28370/dynamic.htm#BHCEJIDC)。私はちょうどそれをテストしながらこれを考え出した。代わりに 'NUMBER'を使用するようにサンプルを更新しました。 –

関連する問題