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

弱く型付けされたSYS_REFCURSORである変数の%ROWTYPEを宣言する方法は?

    簡単に言えば、できません。返される列ごとに変数を定義する必要があります。

    DECLARE
        P_RS SYS_REFCURSOR;
        L_T_COL1 T.COL1%TYPE;
        L_T_COL1 T.COL2%TYPE;
        ...
    

    次に、列のリストにフェッチします:

    FETCH P_RS INTO L_T_COL1, L_T_COL2, ... ;
    

    これは苦痛ですが、参照カーソルで何を期待しているのかを知っている限り、管理できます。 T.*を使用する ただし、プロシージャで列を追加すると、列が何であり、どの順序であるかを認識していると見なすコードが破損するため、これは脆弱になります(テーブルが作成されていない場合は、環境間で分割することもできます)。一貫して-環境によって列の順序が異なる場所を見てきました)。とにかく本当に気になる列だけを選択していることを確認して、決して読まないものの変数を定義する必要がないようにすることをお勧めします。

    11gから、DBMS_SQLを使用できます sys_refcursorを変換するパッケージ DBMS_SQLに カーソルを押すと、それを調べて列を決定できます。実行できることの例として、これにより、すべての行のすべての列の値が、列名とともに出力されます。

    DECLARE
        P_RS SYS_REFCURSOR;
        L_COLS NUMBER;
        L_DESC DBMS_SQL.DESC_TAB;
        L_CURS INTEGER;
        L_VARCHAR VARCHAR2(4000);
    BEGIN
        CAPITALEXTRACT(P_RS => P_RS);
        L_CURS := DBMS_SQL.TO_CURSOR_NUMBER(P_RS);
        DBMS_SQL.DESCRIBE_COLUMNS(C => L_CURS, COL_CNT => L_COLS,
            DESC_T => L_DESC);
    
        FOR i IN 1..L_COLS LOOP
            DBMS_SQL.DEFINE_COLUMN(L_CURS, i, L_VARCHAR, 4000);
        END LOOP;
    
        WHILE DBMS_SQL.FETCH_ROWS(L_CURS) > 0 LOOP
            FOR i IN 1..L_COLS LOOP
                DBMS_SQL.COLUMN_VALUE(L_CURS, i, L_VARCHAR);
                DBMS_OUTPUT.PUT_LINE('Row ' || DBMS_SQL.LAST_ROW_COUNT
                    || ': ' || l_desc(i).col_name
                    || ' = ' || L_VARCHAR);
            END LOOP;
        END LOOP;
    
        DBMS_SQL.CLOSE_CURSOR(L_CURS);
    END;
    /
    

    これはあまり実用的ではありません。簡潔にするために、とにかく印刷したいので、すべての値を文字列として扱います。ドキュメントを見て、より実用的なアプリケーションの例を検索してください。

    refカーソルから数列だけが必要な場合は、l_descをループすることができると思います。 column_nameの位置を記録します 数値変数として、興味のあるものは何でもです。その後、後でその変数で列を参照できます。通常は、カーソルループで名前を使用します。データで何をしているかによって異なります。

    ただし、期待している場合を除きます。 戻ってきた列の順序がわからない場合。これは、プロシージャを制御しているように見えるため、ほとんどありません。また、.*を削除したと仮定します。 s-返される列を必要最小限に減らし、すべてを個別に宣言する方がはるかに良いでしょう。




    1. SQL Server文字列関数(完全なリスト)

    2. Androidカスタムカレンダーとリマインダー

    3. OracleでのLIKEを使用したアクセントと大文字と小文字を区別しない照合

    4. LinqtoOracleを使用する方法はありますか