简体   繁体   English

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

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

I am learning PL/SQL using the Oracle XE's HR database. 我正在使用Oracle XE的HR数据库学习PL / SQL。

I have created the following stored procedure: 我创建了以下存储过程:

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;

I know how to execute it in SQL Developer GUI interface and see the results. 我知道如何在SQL Developer GUI界面中执行它并查看结果。 I also learned from Justin Cave at here and here how to execute it and see the results the SQL*Plus style like so: 我也从中学到贾斯汀洞这里这里如何执行它并查看结果SQL * Plus的风格像这样:

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

I'd like to execute the stored procedure in an anonymous PL/SQL block and see the results in a grid, but it has not been successful. 我想在匿名PL / SQL块中执行存储过程并在网格中查看结果,但它没有成功。

Like what Justin Cave suggested, the following executes just fine, but results are not displayed: 就像Justin Cave建议的那样,以下执行得很好,但结果不会显示:

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

The following will fail: 以下将失败:

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;

The error message says: 错误消息说:

PLS-00320: the declaration of the type of this expression is incomplete or malformed PLS-00320:此表达式类型的声明不完整或格式错误

I don't understand it. 我不明白。 I have been doing that in a few other anonymous PL/SQL blocks and it worked perfectly. 我一直在其他一些匿名PL / SQL块中这样做,它完美地工作。 What's wrong with that line here? 这条线路有什么问题? Can't figure out. 想不通。

I think you are misunderstanding the use of %ROWTYPE. 我认为你误解了%ROWTYPE的使用。 You should just use %ROWTYPE when you are storing all rows from a table. 在存储表中的所有行时,应该只使用%ROWTYPE。 Instead of using %ROWTYPE, make your own type(record) that fits the datatype of the columns that you are fetching. 而不是使用%ROWTYPE,使您自己的类型(记录)适合您要获取的列的数据类型。 Try this: 尝试这个:

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;

I'm sure there is no short answer for this question. 我相信这个问题没有简短的答案。

To understand what the problem is you should investigate what strong typed and weak typed refcursors are. 要了解问题所在,您应该研究强类型和弱类型的反馈器是什么。

Oracle DBMS has no built-in tools to put refcursor results into grid. Oracle DBMS没有内置工具将refcursor结果放入网格中。 If you're gonna write one try DBMS_SQL package and dynamic PL/SQL - it's definitly possible to write a program producing the result you expect (ie putting any sys_refcursor into grid). 如果您要编写一个尝试DBMS_SQL包和动态PL / SQL - 那么就可以编写一个产生您期望的结果的程序(即将任何sys_refcursor放入网格中)。

But if you just started to learn PL/SQL, please don't waste your time now - first, get some experience, and you will see how to do it. 但是如果你刚刚开始学习PL / SQL,请不要浪费你的时间 - 首先,获得一些经验,你会看到如何做到这一点。 And as long as it did not happen, use SQL Developer's hack . 只要没有发生,请使用SQL Developer的hack

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

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