20

MS SQL Server でストアド プロシージャの結果を確認したい場合は、Management Studio で次のように実行します。

--SQL SERVER WAY
exec sp_GetQuestions('OMG Ponies')

結果ペインの出力は次のようになります。

ID    Title                                             ViewCount   Votes 
----- ------------------------------------------------- ---------- --------
2165  Indexed View vs Indexes on Table                  491         2  
5068  SQL Server equivalent to Oracle’s NULLS FIRST     524         3 
1261  Benefits Of Using SQL Ordinal Position Notation?  377         2 

(3 row(s) affected)

ループや PRINT ステートメントを記述する必要はありません。

Oracle で同じことを行うには、SQL Developer で次の匿名ブロックを実行します。

--ORACLE WAY
    DECLARE
        OUTPUT  MYPACKAGE.refcur_question;
        R_OUTPUT MYPACKAGE.r_question;
        USER    VARCHAR2(20);

BEGIN

  dbms_output.enable(10000000);
  USER:= 'OMG Ponies';
  recordCount := 0;



  MYPACKAGE.GETQUESTIONS(p_OUTPUT => OUTPUT, 
  p_USER=> USER, 

  ) ;




  DBMS_OUTPUT.PUT_LINE('ID |  Title | ViewCount | Votes' );

  LOOP 
    FETCH OUTPUT
    INTO R_OUTPUT;

         DBMS_OUTPUT.PUT_LINE(R_OUTPUT.QUESTIONID || '|' || R_OUTPUT.TITLE 
               '|' || R_OUTPUT.VIEWCOUNT '|' || R_OUTPUT.VOTES);
          recordCount := recordCount+1;




 EXIT WHEN OUTPUT % NOTFOUND;  
      END LOOP;
      DBMS_OUTPUT.PUT_LINE('Record Count:'||recordCount);
      CLOSE OUTPUT;


    END;

これは次のように出力されます

ID|Title|ViewCount|Votes 
2165|Indexed View vs Indexes on Table|491|2  
5068|SQL Server equivalent to Oracle’s NULLS FIRST|524|3 
1261|Benefits Of Using SQL Ordinal Position Notation?|377|2 
Record Count: 3

したがって、SQL バージョンには 1 行、オラクルには 18 行あり、出力は醜いです。多くの列がある場合やデータが数値である場合は、さらに悪化します。

これについて私が奇妙なのは、このステートメントをSQL DeveloperまたはManagement studioのいずれかで書くと...

SELECT 
ID, 
Title, 
ViewCount, 
Votes
FROM votes where user = 'OMG Ponies'  

結果はかなり似ています。これにより、テクニックが不足しているか、間違ったツールを使用しているように感じます。

4

3 に答える 3

17

refcursor を返す関数である場合GetQuestions、これは SQL Server バージョンにあると思われるものであり、代わりに次のようなことができる場合があります。

select * from table(MyPackage.GetQuestions('OMG Ponies'));

または、PL/SQL ブロックで必要な場合は、カーソルで同じ選択を使用できます。

代わりに関数にdbms_outputステートメントを生成させることもできるため、デバッグにいつでも使用できますが、少しオーバーヘッドが追加されます。

編集

cast()うーん、パッケージの外部で独自の型 (およびその型のテーブル) を宣言しない限り、返された refcursor を使用可能な型にすることが可能かどうかはわかりません。ただし、結果をダンプするためだけにこれを行うことができます。

create package mypackage as
    function getquestions(user in varchar2) return sys_refcursor;
end mypackage;
/

create package body mypackage as
    function getquestions(user in varchar2) return sys_refcursor as
        r sys_refcursor;
    begin
        open r for
            /* Whatever your real query is */
            select 'Row 1' col1, 'Value 1' col2 from dual
            union
            select 'Row 2', 'Value 2' from dual
            union
            select 'Row 3', 'Value 3' from dual;
            return r;
    end;
end mypackage;
/

var r refcursor;
exec :r := mypackage.getquestions('OMG Ponies');
print r;

また、呼び出しの結果を別のプロシージャまたは関数で使用できます。少しトリッキーに見えるのは、PL/SQLの外側にあるだけです。

追加するために編集:このアプローチでは、それが手順であれば、本質的に同じことができます:

var r refcursor;
exec mypackage.getquestions(:r, 'OMG Ponies');
print r;
于 2010-08-19T23:18:53.467 に答える
2

SQL Developerは、ストアド プロシージャの実行からの出力を自動的にキャッチします。ストアド プロシージャをプロシージャ エディタから直接実行すると、この動作の詳細がこちらの投稿で確認できます。

SQL開発者向けヒント: REFCURSOR出力の表示

ここで、SQL ワークシートの anon ブロックの一部として refcursor を実行する場合は、次のようにすることができます。

var rc refcursor
exec :rc := GET_EMPS(30)
print rc

-- GET_EMPS() は sp_GetQuestions('OMG Ponies') 呼び出しになります。PRINT コマンドは、ストアド プロシージャを介して実行される「クエリ」からの出力を送信し、次のようになります。

anonymous block completed
RC
-----------------------------------------------------------------------------------------------------
EMPLOYEE_ID FIRST_NAME           LAST_NAME                 EMAIL                     PHONE_NUMBER         HIRE_DATE                 JOB_ID     SALARY     COMMISSION_PCT MANAGER_ID DEPARTMENT_ID 
----------- -------------------- ------------------------- ------------------------- -------------------- ------------------------- ---------- ---------- -------------- ---------- ------------- 
114         Den                  Raphaely                  DRAPHEAL                  515.127.4561         07-DEC-94 12.00.00        PU_MAN     11000                     100        30            
115         Alexander            Khoo                      AKHOO                     515.127.4562         18-MAY-95 12.00.00        PU_CLERK   3100                      114        30            
116         Shelli               Baida                     SBAIDA                    515.127.4563         24-DEC-97 12.00.00        PU_CLERK   2900                      114        30            
117         Sigal                Tobias                    STOBIAS                   515.127.4564         24-JUL-97 12.00.00        PU_CLERK   2800                      114        30            
118         Guy                  Himuro                    GHIMURO                   515.127.4565         15-NOV-98 12.00.00        PU_CLERK   2600                      114        30            
119         Karen                Colmenares                KCOLMENA                  515.127.4566         10-AUG-99 12.00.00        PU_CLERK   2500                      114        30            

さて、あなたは10gと言いました。12c を使用している場合は、PL/SQL エンジンが拡張され、暗黙的なカーソルの結果がサポートされるようになりました。したがって、これは少し簡単になり、カーソルを設定する必要がなくなります。ここに記載されているように、データを取得するための呼び出しを行うだけです。

于 2014-07-23T18:54:51.890 に答える
0
/*
    Create Sample Package in HR Schema
*/

CREATE OR REPLACE PACKAGE PRINT_REF_CURSOR
AS
    PROCEDURE SP_S_EMPLOYEES_BY_DEPT (
        p_DEPARTMENT_ID   IN  INTEGER,
        Out_Cur OUT SYS_REFCURSOR); 

END PRINT_REF_CURSOR;        

CREATE OR REPLACE PACKAGE BODY PRINT_REF_CURSOR
AS

    PROCEDURE SP_S_EMPLOYEES_BY_DEPT (
        p_DEPARTMENT_ID   IN  INTEGER,
        Out_Cur OUT SYS_REFCURSOR)
    AS 
    BEGIN
      OPEN Out_Cur FOR
           SELECT *
             FROM EMPLOYEES
             WHERE DEPARTMENT_ID = p_DEPARTMENT_ID;
    EXCEPTION
      WHEN NO_DATA_FOUND
      THEN
         DBMS_OUTPUT.Put_Line('SP_S_EMPLOYEES_BY_DEPT' || ',' || '-20000' || ',' );
      WHEN OTHERS
      THEN
         DBMS_OUTPUT.Put_Line('SP_S_EMPLOYEES_BY_DEPT' || ',' || '-20001' || ',' );    
    END SP_S_EMPLOYEES_BY_DEPT;         

END PRINT_REF_CURSOR;    

/*
    Fetch values using Ref Cursor and display it in grid.
*/

var RC refcursor;

DECLARE 
    p_DEPARTMENT_ID NUMBER;
    OUT_CUR SYS_REFCURSOR;

BEGIN 
  p_DEPARTMENT_ID := 90;
  OUT_CUR := NULL;

  PRINT_REF_CURSOR.SP_S_EMPLOYEES_BY_DEPT ( p_DEPARTMENT_ID, OUT_CUR);
  :RC := OUT_CUR;

END;
/
PRINT RC;  
/************************************************************************/  
于 2014-02-01T10:53:43.200 に答える