繁体   English   中英

如何在匿名PL / SQL块中使用out cursor参数执行oracle过程?

[英]How to execute an oracle procedure with an out cursor parameter in an anonymous PL/SQL block?

我正在使用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界面中执行它并查看结果。 我也从中学到贾斯汀洞这里这里如何执行它并查看结果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块中这样做,它完美地工作。 这条线路有什么问题? 想不通。

我认为你误解了%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;

我相信这个问题没有简短的答案。

要了解问题所在,您应该研究强类型和弱类型的反馈器是什么。

Oracle DBMS没有内置工具将refcursor结果放入网格中。 如果您要编写一个尝试DBMS_SQL包和动态PL / SQL - 那么就可以编写一个产生您期望的结果的程序(即将任何sys_refcursor放入网格中)。

但是如果你刚刚开始学习PL / SQL,请不要浪费你的时间 - 首先,获得一些经验,你会看到如何做到这一点。 只要没有发生,请使用SQL Developer的hack

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM