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
を作ることができる:
UPDATE:BOOLEAN
変数をバインドすることはできないようです、この例では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
にアクセスすることはできません
可能な回避策は、動的ステートメントにいくつかの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;
あなたは私に例を教えていただけますか? – matyyyy
残念ながらBOOLEANはSQL型ではありません。そのためにエラーが発生します。 – matyyyy
是非、ここで説明した通りです(http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28370/dynamic.htm#BHCEJIDC)。私はちょうどそれをテストしながらこれを考え出した。代わりに 'NUMBER'を使用するようにサンプルを更新しました。 –