Oracle PLSQL refcursor%ROWTYPE该表达式类型的声明不完整或格式错误

时间:2019-06-17 09:41:53

标签: oracle oracle11g

我想在PL / SQL代码中分配游标变量,然后从中获取一行。当我明确声明游标时,它可以工作。

DECLARE
cursor c1 is SELECT * from acme;
row1 c1%ROWTYPE;

但是当我使用代码为每个对象分配光标时像这样Oracle PLSQL setting a cursor from a variable

  c1 sys_refcursor;
  r1 c1%ROWTYPE;

我收到错误

  

此表达式类型的声明不完整或   格式错误

只写r1 %ROWTYPE也会产生错误。

按照变量的一般用法说明,例如在这里How to declare variable and use it in the same Oracle SQL script?,我已经尝试过:

SET SERVEROUTPUT ON
DECLARE
  c1 sys_refcursor;
BEGIN
    open c1 for 'SELECT * FROM foo';
    declare r1 c1%ROWTYPE;
    begin
        fetch c1 into r1; 
    end;
    DBMS_OUTPUT.PUT_LINE('FOO');    
    close c1;
END;

再次得到the declaration of the type of this expression is incomplete or malformed

如何为我的情况声明行类型的变量? Oracle 11g。
附言解决方法是fetch c1 into v_empno, v_ename, ect声明几个变量,仍然可以使用行类型一吗?

2 个答案:

答案 0 :(得分:1)

如果您打算显示任何给定查询的结果,则可以使用类似于this AskTOM article

中描述的标准过程。
create or replace procedure return_result( l_query varchar2 )
   is
       l_theCursor     integer default dbms_sql.open_cursor;
       l_columnValue   varchar2(4000);
       l_status        integer;
       l_colCnt        number := 0;
       l_separator     varchar2(1);
       l_descTbl       dbms_sql.desc_tab;
   begin
       dbms_sql.parse(  l_theCursor,  l_query, dbms_sql.native );

       dbms_sql.describe_columns( l_theCursor, l_colCnt, l_descTbl );


           l_separator := '';
           for i in 1 .. l_colCnt loop
               dbms_output.put( l_separator || l_descTbl(i).col_name );
               l_separator := ',';
           end loop;
           dbms_output.put_line('');

        for i in 1 .. l_colCnt loop
           dbms_sql.define_column( l_theCursor, i, l_columnValue, 4000 );
       end loop;
       l_status := dbms_sql.execute(l_theCursor);

       while ( dbms_sql.fetch_rows(l_theCursor) > 0 ) loop
           l_separator := '';
           for i in 1 .. l_colCnt loop
               dbms_sql.column_value( l_theCursor, i, l_columnValue );
               dbms_output.put( l_separator || l_columnValue );
               l_separator := ',';
           end loop;
           dbms_output.new_line;
       end loop;
       dbms_sql.close_cursor(l_theCursor);
   end;
 /

将任何查询传递给此过程以获取结果。

set serveroutput on
set feedback off
set sqlformat ansiconsole
set pages 0
BEGIN
return_result('select e.employee_id,e.first_name,e.salary,
          d.department_name from 
          employees e join 
  departments d on e.department_id= d.department_id');
END;
/

结果

EMPLOYEE_ID,FIRST_NAME,SALARY,DEPARTMENT_NAME
200,Jennifer,4400,Administration
201,Michael,13000,Marketing
202,Pat,6000,Marketing
114,Den,11000,Purchasing

注意:Oracle 12c提供了DBMS_SQL.RETURN_RESULT,使用它可以轻松地实现此过程。

答案 1 :(得分:0)

像这样吗?

SQL> set serveroutput on
SQL>
SQL> declare
  2    c1 sys_refcursor;
  3    r1 dept%rowtype;                      --> this
  4  begin
  5    open c1 for 'select * from dept';
  6    fetch c1 into r1;
  7    dbms_output.put_line(r1.dname);
  8  end;
  9  /
ACCOUNTING

PL/SQL procedure successfully completed.

SQL>