Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在匿名PL/SQL块中使用out cursor参数执行oracle过程?_Oracle_Plsql_Sys Refcursor_Oracle Cursor_Recordtype - Fatal编程技术网

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

如何在匿名PL/SQL块中使用out cursor参数执行oracle过程?,oracle,plsql,sys-refcursor,oracle-cursor,recordtype,Oracle,Plsql,Sys Refcursor,Oracle Cursor,Recordtype,我正在使用OracleXe的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_n

我正在使用OracleXe的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;
我知道如何在SQLDeveloperGUI界面中执行它并查看结果。我还从at学习了如何执行它,以及如何使用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;

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

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

Oracle DBMS没有内置工具将refcursor结果放入网格。如果您要编写一个DBMS_SQL包和动态PL/SQL,那么编写一个程序生成您期望的结果(即将任何sys_refcursor放入网格)是完全可能的


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

ref游标与普通游标不同;您在其他块中到底做了什么-使用普通光标的rowtpe,但我不确定这样做对你有什么帮助。我不完全确定您的qestion是什么-为什么会出现这个错误,或者您正在寻找如何在网格视图中获得ref游标?还是别的什么?还显示了通过“代码编辑器”对话框在网格中获取结果的方法。这可能是其中一个问题的重复,但不确定是哪一个。@AlexPoole:我想我已经清楚地说明了我一直在尝试做什么:
我想在匿名PL/SQL块中执行存储过程,并在网格中查看结果,但没有成功。
是,我说我知道如何通过SQL Developer GUI界面执行它,你说的代码编辑器对话框:
我知道如何在SQL Developer GUI界面中执行它并查看结果。
是的,但你问的唯一实际问题是“这行有什么问题?”这似乎与网格部分无关。我链接的第二个问题是否有助于网格输出?谢谢。您是指表中的所有列吗?您是否表示%rowtype只能应用于静态游标?感谢您让我知道没有内置工具可以将refcursor结果放入网格。我确实在我的原始帖子中说过,我知道如何通过SQL Developer GUI界面查看结果,这就是您所说的黑客。@Stack0verflow,那么“网格”是什么意思呢?描述一个你想要解决问题的“理想界面”。附言:我看到唯一的问题是“这条线怎么了?”。我认为如果您得到这样的回答,您将不会满意:“定义弱引用游标的%ROWTYPE是错误的,因为它的ROWTYPE在编译时是未知的。”。所以我再问你-你想要什么?谢谢。所以,正如我们所知,SQLDeveloper能够在网格中显示ref cursor结果集,正如您提到的那样。但SQLDeveloper并没有向我们展示生成的脚本(就像SQLServerManagementStudio一样)。所以我想问题是,SQL开发人员是如何做到的?在运行时,您可以使用
DBMS\u SQL.description\u columns
过程在任何ref游标中获取列的类型和名称。然后使用相同的包获取行。流水线函数可以帮助将获取的结果放入网格。我很惊讶,在这个问题上没有众所周知的讨论。我对这个问题有一个完整的解决方案,但我无权发表。所以,您可以自己编写,或者询问SQL开发团队他们是如何做到的。这非常有趣。谢谢