1

Oracle XE の HR データベースを使用して PL/SQL を学習しています。

次のストアド プロシージャを作成しました。

CREATE OR REPLACE PROCEDURE get_employees( p_country_id IN CHAR
                                         , p_emp        OUT SYS_REFCURSOR) 
IS
BEGIN

  OPEN p_emp FOR
    SELECT e.first_name
          ,e.last_name
          ,e.department_id
          ,d.department_name
          ,l.city
          ,l.state_province
      FROM employees e
     INNER JOIN departments d
        ON e.department_id = d.department_id
     INNER JOIN locations l
        ON d.location_id = l.location_id
     WHERE l.country_id = p_country_id; 
END;

SQL Developer GUIインターフェイスで実行して結果を確認する方法を知っています。また、 Justin Caveからここここでそれを実行し、SQL*Plus スタイルの結果を次のように確認する方法も学びました。

VARIABLE CE REFCURSOR;
EXEC GET_EMPLOYEES('US', :CE);
PRINT CE;

匿名の PL/SQL ブロックでストアド プロシージャを実行し、グリッドで結果を確認したいのですが、うまくいきませんでした。

Justin Cave が提案したように、以下は問題なく実行されますが、結果は表示されません。

DECLARE
  C_EMP SYS_REFCURSOR;
BEGIN
  GET_EMPLOYEES('US', C_EMP);
END;

以下は失敗します。

DECLARE
  C_EMP SYS_REFCURSOR;
  L_REC C_EMP%ROWTYPE; --THIS LINE FAILS.
BEGIN
  GET_EMPLOYEES('US', C_EMP);
  -- LOOP AND FETCH GOES HERE.
END;

エラーメッセージには次のように記載されています。

PLS-00320: この式の型の宣言が不完全であるか、形式が正しくありません

わかりません。私は他のいくつかの匿名PL/SQLブロックでそれを行ってきましたが、完全に機能しました。ここの行の何が問題になっていますか? わかりません。

4

2 に答える 2

2

%ROWTYPE の使い方を誤解していると思います。テーブルのすべての行を格納する場合は、%ROWTYPE を使用する必要があります。%ROWTYPE を使用する代わりに、フェッチする列のデータ型に適合する独自の型 (レコード) を作成します。これを試して:

DECLARE
  C_EMP SYS_REFCURSOR;
  TYPE new_type IS RECORD(FIRST_NAME VARCHAR2(100), LAST_NAME VARCHAR2(200), DEPARTMENT_ID NUMBER, DEPARTMENT_NAME VARCHAR2(200), CITY VARCHAR2(200), STATE_PROVINCE VARCHAR2(200));
  L_REC new_type; --instead of using %ROWTYPE, use the declared type
BEGIN
  GET_EMPLOYEES('US', C_EMP);
  LOOP
 FETCH c_emp INTO l_rec;
 EXIT WHEN c_emp%NOTFOUND;

     dbms_output.put_line(l_rec.first_name||'_'||
                          l_rec.last_name||'_'||
                          l_rec.department_id||'_'||
                          l_rec.department_name||'_'||
                          l_rec.city||'_'|| 
                          l_rec.state_province);
 END LOOP;

CLOSE c_emp;
END;
于 2015-10-22T01:53:05.047 に答える
1

この質問に対する簡単な答えはないと確信しています。

問題が何であるかを理解するには、強い型付けされた参照カーソルと弱い型付けされた参照カーソルが何であるかを調査する必要があります。

Oracle DBMS には、refcursor の結果をグリッドに配置する組み込みツールがありません。DBMS_SQL パッケージと動的 PL/SQL を試してみる場合は、期待する結果を生成するプログラムを作成することは間違いなく可能です (つまり、任意の sys_refcursor をグリッドに配置します)。

しかし、PL/SQL の学習を始めたばかりの場合は、時間を無駄にしないでください。まず、ある程度の経験を積むと、その方法がわかります。そして、それが起こらない限り、SQL Developer のhackを使用してください。

于 2015-10-22T07:45:47.717 に答える