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

列名でカーソルに動的にアクセスする

    パッケージ DBMS_SQLを使用できます。 動的クエリでカーソルを作成してアクセスします。

    ただし、DBMS_SQLであるため、名前で列にアクセスするのは実際には簡単ではありません。 パッケージはポジショニングを使用しており、動的クエリでは、実行前に列の順序がわからない場合があります。

    さらに、この質問のコンテキストでは、コンパイル時に表示する列がわからない可能性があるため、表示する列がパラメーターとして指定されていると想定します。

    DBMS_SQL.describe_columnsを使用できます SELECTの列を分析します 列の動的マッピングを構築するために解析された後にクエリを実行します。すべての列をVARCHAR2にキャストできると想定します DBMS_OUTPUTで表示したいので 。

    次に例を示します。

    SQL> CREATE OR REPLACE PROCEDURE display_query_column(p_query VARCHAR2,
      2                                                   p_column VARCHAR2) IS
      3     l_cursor            INTEGER;
      4     l_dummy             NUMBER;
      5     l_description_table dbms_sql.desc_tab3;
      6     TYPE column_map_type IS TABLE OF NUMBER INDEX BY VARCHAR2(32767);
      7     l_mapping_table column_map_type;
      8     l_column_value  VARCHAR2(4000);
      9  BEGIN
     10     l_cursor := dbms_sql.open_cursor;
     11     dbms_sql.parse(l_cursor, p_query, dbms_sql.native);
     12     -- we build the column mapping
     13     dbms_sql.describe_columns3(l_cursor, l_dummy, l_description_table);
     14     FOR i IN 1 .. l_description_table.count LOOP
     15        l_mapping_table(l_description_table(i).col_name) := i;
     16        dbms_sql.define_column(l_cursor, i, l_column_value, 4000);
     17     END LOOP;
     18     -- main execution loop
     19     l_dummy := dbms_sql.execute(l_cursor);
     20     LOOP
     21        EXIT WHEN dbms_sql.fetch_rows(l_cursor) <= 0;
     22        dbms_sql.column_value(l_cursor, l_mapping_table(p_column), l_column_value);
     23        dbms_output.put_line(l_column_value);
     24     END LOOP;
     25     dbms_sql.close_cursor(l_cursor);
     26  END;
     27  /
    
    Procedure created
    

    このプロシージャは、実行時にのみ認識されるクエリで呼び出すことができます:

    SQL> set serveroutput on
    SQL> exec display_query_column('SELECT * FROM scott.emp WHERE rownum < 5', 'ENAME');
    SMITH
    ALLEN
    WARD
    JONES
    
    PL/SQL procedure successfully completed
    
    SQL> exec display_query_column('SELECT * FROM scott.emp WHERE rownum < 5', 'EMPNO');
    7369
    7499
    7521
    7566
    
    PL/SQL procedure successfully completed
    

    動的SQLには注意してください。ユーザーと同じ権限を持っているため、DMLおよびDDLを実行できます。 このスキーマで許可されているステートメント。

    たとえば、上記の手順を使用して、テーブルを作成または削除できます。

    SQL> exec display_query_column('CREATE TABLE foo(id number)', '');
    begin display_query_column('CREATE TABLE foo(id number)', ''); end;
    ORA-01003: aucune instruction analysée
    ORA-06512: à "SYS.DBMS_SQL", ligne 1998
    ORA-06512: à "APPS.DISPLAY_QUERY_COLUMN", ligne 13
    ORA-06512: à ligne 1
    
    SQL> desc foo
    Name Type   Nullable Default Comments 
    ---- ------ -------- ------- -------- 
    ID   NUMBER Y      
    


    1. PostgreSQL:有効な変数割り当てサンプル?

    2. 外部キー制約を組み合わせたmysqldbcopy?

    3. 列の最大値に基づいてレコードを取得する

    4. ファイルまたはアセンブリを読み込めません'crystaldecisions.windows.forms,version=13.0.2000.0'