2015-10-21 83 views
1

我正在使用Oracle XE的HR数据库学习PL/SQL。如何在匿名PL/SQL块中使用out游标参数执行oracle过程?

我创建了以下存储过程:

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开发GUI界面执行它,并查看结果。我也从Justin Cave处了解到herehere如何执行它并查看结果SQL * Plus的风格像这样:

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

我想在一个匿名PL/SQL块执行存储过程和看在网格中的结果,但它并没有成功。

像什么贾斯汀洞的建议,下面执行得很好,但结果不显示:

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块中这样做,并且它工作得很好。这条线有什么问题?无法弄清楚。

+1

引用游标与普通游标不相同;你在其他方块中做了什么 - 使用普通光标的rowtpe? [你不能这样做](http://stackoverflow.com/q/11187376/266304),但我不知道如何做到这一点无论如何会帮助你。我不完全确定你的问题是什么 - 为什么你会得到这个错误,或者你在寻找如何在网格视图中获取引用光标?或者是其他东西? –

+1

[This answer](http://stackoverflow.com/a/27006514/266304)还显示了一种通过代码编辑器对话框在网格中获取结果的方法。这可能是这些问题之一的重复,但不确定哪一个。 –

+0

@AlexPoole:我想我已经明确了我一直在试图做的事情:'我想在一个匿名的PL/SQL块中执行存储过程,并在网格中查看结果,但它并未成功。' – Stack0verflow

回答

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; 
+0

谢谢。你的意思是表中的所有*列?你是否指出%rowtype只能应用于静态游标? – Stack0verflow

1

我敢肯定这个问题没有简短的答案。

要了解问题所在,应该调查强类型和弱类型的refcursors。

Oracle DBMS没有内置工具将refcursor结果放入网格中。如果你想写一个DBMS_SQL包和动态PL/SQL,你可以编写一个程序来产生你期望的结果(即把任何sys_refcursor放入网格中)。

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

+0

感谢您告诉我,没有内置工具将refcursor结果放入网格中。我在我原来的文章中说过,我知道如何通过SQL Developer GUI界面查看结果,这就是你正在讨论的黑客攻击。 – Stack0verflow

+0

@ StackOverflow,那么你是什么意思的“网格”?描述你想解决你的问题的“理想界面”。 PS:我看到唯一的问题“这里有什么问题?”。我认为如果你得到这样的答案,你就不会满意:“定义弱引用游标的%ROWTYPE是错误的,因为在编译时rowtype是未知的。”所以我问你 - 你想得到什么? – diziaq

+0

谢谢。因此,正如我们所知,SQL Developer能够在网格中显示引用游标结果集,这是您提到的黑客攻击。但是SQL Developer没有向我们展示生成的脚本(比如SQL Server Management Studio)。所以我想问题是,SQL Developer如何做到这一点? – Stack0verflow