sql >> データベース >  >> RDS >> Oracle

テーブルに格納されているSQLクエリを実行する

    これは非常に特殊な要件のようであり、堅牢な方法で解決するのは難しいでしょう。 STMT_OR_VALUEは、One ColumnTwoUsagesアンチパターンの実施形態です。さらに、STMT_OR_VALUEを解決するには、フロー制御ロジックと動的SQLの使用が必要です。したがって、純粋なSQLソリューションにすることはできません。動的クエリをアセンブルして実行するには、PL/SQLを使用する必要があります。

    これがソリューションの概念実証です。 SQLから呼び出すことができる関数を選択しました。これは、1つの仮定に依存します。TEST1.STMT_OR_VALUEに挿入するすべてのクエリ文字列には、単一の数値列の射影があります。 すべての値の文字列は数値データのみのCSVです 。この条件を使用すると、動的クエリを実行するか、文字列を一連の数値にトークン化する関数を簡単に作成できます。どちらもネストされたテーブルにまとめて収集されます:

    create or replace function get_ids (p_name in test1.name%type) 
      return sys.odcinumberlist
    is
      l_rec test1%rowtype;
      return_value sys.odcinumberlist;
    begin
    
      select * into l_rec
      from test1
      where name = p_name;
    
      if l_rec.type = 'SQL_QUERY' then 
        -- execute a query
        execute immediate l_rec.stmt_or_value
          bulk collect into return_value;
      else
        -- tokenize a string
        select xmltab.tkn
        bulk collect into return_value
        from ( select l_rec.stmt_or_value from dual) t
            , xmltable(  'for $text in ora:tokenize($in, ",") return $text'
                          passing stmt_or_value as "in"
                          columns tkn number path '.'
                       ) xmltab;
      end if;
      return return_value;
    end;
    /
    

    動的SQLステートメントを実行する方法は複数あり、CSVを一連の数値にトークン化する方法は複数あることに注意してください。私の決定は恣意的です:ここであなたの好みの方法を自由に置き換えてください。

    この関数は、table()を使用して呼び出すことができます 電話:

    select * 
    from data
    where id in ( select * from table(get_ids('first'))) -- execute query
    or    id in ( select * from table(get_ids('second'))) -- get string of values
    /
    

    このアプローチの大きな利点は、STMT_OR_VALUEの評価に関するロジックをカプセル化し、動的SQLの使用を隠すことです。したがって、読みやすさを維持しながらSQLステートメントで使用したり、IDのセットを生成するためのメカニズムをさらに追加したりするのは簡単です。

    ただし、このソリューションは脆弱です。 test1の値が テーブルはルールに従います。つまり、それらは単一の数値のストリームに変換可能である必要があるだけでなく、SQLステートメントはEXECUTEIMMEDIATEによって有効で実行可能である必要があります。たとえば、質問のサンプルデータの末尾のセミコロンは無効であり、EXECUTEIMMEDIATEがスローされます。動的SQLは、コンパイルエラーをランタイムエラーに変換するため、特に困難です。



    1. mysql_fetch_assoc()の問題を解決する方法

    2. SQL Serverの丸め誤差、異なる値を指定

    3. Oracle 9iが空の文字列をNULLとして扱うのはなぜですか?

    4. XML_LOAD()を使用してXMLファイルをMySQLデータベーステーブルにインポートする方法。働き