web-dev-qa-db-ja.com

アウトカーソルの構造を決定する

私はOracleに、私も私のチームも作成しておらず、非常に難読化されている機能を持っています。ただし、カーソル出力パラメータがあります。カーソルに含まれる数とタイプを確認するにはどうすればよいですか?

必要なものの例として、次のカーソルについて考えてみます。

DECLARE
  TEMP1 VARCHAR2(500);
  TEMP2 NUMBER;
  TEMP3 RAW(16);
  TEMP SYS_REFCURSOR;
  PROCEDURE MAKE_TEMP(TEMP_RETURN OUT SYS_REFCURSOR) IS
  BEGIN
    OPEN TEMP_RETURN FOR SELECT DUMMY, 5, HEXTORAW('111') FROM DUAL;
  END;
BEGIN
  MAKE_TEMP(TEMP);
  LOOP
    FETCH TEMP INTO TEMP1, TEMP2, TEMP3;
    EXIT WHEN (TEMP%NOTFOUND);
    DBMS_OUTPUT.PUT_LINE('1: '||TEMP1);
    DBMS_OUTPUT.PUT_LINE('2: '||TO_CHAR(TEMP2));
    DBMS_OUTPUT.PUT_LINE('3: '||RAWTOHEX(TEMP3));
  END LOOP;
  CLOSE TEMP;
END;
/

MAKE_TEMPが使用しようとしている関数である場合、行ごとに3つの値があり、値がVARCHAR2NUMBER、およびであることを知る必要があります。 RAWをこの順序で指定して、結果を保持する変数を定義できるようにします。

私はOracle11.2.0.1.0を使用していますが、新しいバージョンの回答もあれば幸いです。

ソースだけを見ることができない理由

知っておく必要がある場合、この関数はOracle ASP.NETメンバーシッププロバイダーの一部であり、Oracleによって作成されています。問題をデバッグしようとしていますが、この関数が何を返すのかを確認したいと思います。関数のソースコードは次のように始まります。

create or replace 
FUNCTION  "ORA_ASPNET_MEM_GETALLUSERS" wrapped
0
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
3
8
9200000
1
4
0
33

ご覧のとおり、そのカーソルに関する情報を抽出することは(せいぜい)非常に困難です。

1
jpmc26

このサンプルコードは、ref_cursorを解析する方法を示しています。使用可能な追加の列があります。使用可能な列の完全なリストについては、SYS.DBMS_SQL.desc_tab2の定義を参照してください。

この例では、私のref_cursorselect * from user_tablesとして定義されています。もちろん、あなたはあなた自身のref_cursorで代用するでしょう。

DECLARE
   l_csrid       INTEGER;
   l_coldesc     SYS.DBMS_SQL.desc_tab2;
   l_colcnt      INTEGER;
   l_refcursor   SYS_REFCURSOR;

   FUNCTION tostring (p_label   IN VARCHAR2
                     , p_value   IN VARCHAR2)
      RETURN VARCHAR2
   AS
   BEGIN
      RETURN RPAD (p_label, 30)
             || ': '
             || p_value
             || UTL_TCP.crlf;
   END tostring;

   PROCEDURE myput_line (p_rec      IN DBMS_SQL.desc_rec2
                       , p_colnum   IN INTEGER)
   AS
   BEGIN
      DBMS_OUTPUT.put_line (   RPAD ('_', 30, '_') 
                        || UTL_TCP.crlf
                        || tostring (p_label => 'Column'
                                   , p_value => p_colnum)
                        || tostring (p_label => 'Name'
                                   , p_value => p_rec.col_name)
                        || tostring (p_label => 'Type'
                                   , p_value => p_rec.col_type)
                        || tostring (p_label => 'Null OK'
                                   , p_value => CASE WHEN p_rec.col_null_ok
                                                     THEN 'Yes' 
                                                     ELSE 'No' 
                                                END));
   END myput_line;
 BEGIN
   OPEN l_refcursor FOR
      SELECT * FROM user_tables;

   l_csrid   := DBMS_SQL.to_cursor_number (rc => l_refcursor);
   DBMS_SQL.describe_columns2 (c       => l_csrid
                             , col_cnt => l_colcnt
                             , desc_t  => l_coldesc);

   FOR i IN 1 .. l_colcnt LOOP
      myput_line (l_coldesc (i), i);
   END LOOP;
END;
3
user88846