2016-04-19 11 views
3

Oracleの動的SQLでは、SQL文を含む文字列を実行できます。例えば動的SQL - 構文およびセマンティクスのチェック

l_stmt := 'select count(*) from tab1'; 
execute immediate l_stmt; 

それはl_stmtを実行しますが、構文とセマンティクスがprogrammitically正しいことを確認していないことは可能ですか?

+2

ステートメントを準備します。 – jarlh

+1

'DBMS_SQL.PARSE()'を使用できます。https://docs.oracle.com/database/121/ARPLS/d_sql.htm#ARPLS68277 –

+1

参照http://stackoverflow.com/a/3873881/18747 –

答えて

0

私は唯一の「解決策」はDBMS_SQL.PARSE()を使用することであると思います。

これは完璧ではありませんが、それはあなたが

+1

それをチェックします:DDL文のために、これが唯一の文を解析しないことを心に留めておくが、それは同様にそれを実行します。 – sstan

-1

このようにすれば、実行前に作成されたクエリを確認できます。

set serveroutput on; 
DECLARE 
lv_sql VARCHAR2(1000); 
lv_cnt PLS_INTEGER; 
BEGIN 
lv_sql:='select count(*) from tab1'; 
dbms_output.put_line(lv_sql); 
--EXECUTE IMMEDIATE lv_sql INTO lv_cnt; 
END 
+2

これはどのように構文とセマンティクスをチェックしますか? –

+0

基本的には、dbms_outputの印刷データを使用して、実行時エラーを回避するためにワークシートで実行します。そして、これは多くの動的条件を伴う巨大な動的クエリを扱っているときに非常に悪いことです。 –

+0

私は投票の理由を知っていますか? –

1

EXPLAIN PLANは、SQL文のほぼすべてのタイプの構文とセマンティクスをチェックします得ることができる最善の方法です。 DBMS_SQL.PARSEとは異なり、暗黙的に何も実行しません。

説明計画のポイントは、Oracleがどのように文を実行するかを示すことです。プランを生成する副作用として、シンタックスや権限をチェックし、実際にそのステートメントを実行する以外はすべてを実行する必要があります。 Explainプラン自体は無意味であり、無視することができます。ステートメントは、エラーをチェックするためにのみ実行されます。エラーがなければ、このステートメントは有効です。

たとえば、次のPL/SQLブロックでは、SELECT文とCREATE TABLE文の妥当性をチェックします。それらはエラーなしで実行されるので、構文は正常です。

begin 
    execute immediate 'explain plan for select * from dual'; 
end; 
/

begin 
    execute immediate 'explain plan for create table just_some_table(a number)'; 
end; 
/

不正なステートメントを実行するとエラーが発生します。少なくともこの1つのテストケースでは、文が単独で実行された場合と同じエラーが生成されます。

begin 
    execute immediate 'explain plan for select * from this_table_does_not_exist'; 
end; 
/
ORA-00942: table or view does not exist 
ORA-06512: at line 2 

マニュアルの構文図は、それがのためにすべてののステートメントを実行する必要がありますを意味します。しかし、動作しない文の型が少なくともいくつかあるようです(たとえば、ALTER SESSION)。

begin 
    execute immediate 'explain plan for alter session set optimizer_features_enable = ''11.2.0.4'''; 
end; 
/
ORA-00900: invalid SQL statement 
ORA-06512: at line 2 

ちょっとオフトピック - あなたがPL/SQLに建てプライベートSQLフィドルのように、完全に汎用的なSQLインタフェースを構築しようとしていますか?ユーザーが特定のステートメントタイプを実行しようとしないようにしたり、末尾にセミコロンがないようにするなどのことについて心配する必要はありますか?もしそうなら、難しい動的SQLタスクのいくつかに役立つ質問を編集することができます。

関連する問題