Oracle PL SQL ref cursor%ROWTYPE 此表达式的类型声明不完整或格式错误
Posted
技术标签:
【中文标题】Oracle PL SQL ref cursor%ROWTYPE 此表达式的类型声明不完整或格式错误【英文标题】:Oracle PLSQL refcursor%ROWTYPE the declaration of the type of this expression is incomplete or malformed 【发布时间】:2019-06-17 09:41:53 【问题描述】:我想在 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
我该如何声明行类型的变量呢?甲骨文 11g.
附:解决方法是 fetch c1 into v_empno, v_ename, ect
声明几个变量,还有没有办法使用 rowtype one?
【问题讨论】:
简短答案 -sys_refcursor
没有定义任何列,因此它没有 %rowtype
,并且在编译时也没有动态引用光标。
@William Robertson,谢谢。我已经实施了某种解决方法,因为我的查询仍然不同。
【参考方案1】:
这样的?
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>
【讨论】:
我想使用 refcursor 变量的原因是我在循环中为它分配了不同的选择,使用连接和外部数据库链接进行选择。 据我所知,你不能那样做;您必须将每个引用游标的列提取到其自己的变量中。【参考方案2】:如果您打算显示任何给定查询的结果,您可以使用类似于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
,使用它可以轻松实现此过程。
【讨论】:
以上是关于Oracle PL SQL ref cursor%ROWTYPE 此表达式的类型声明不完整或格式错误的主要内容,如果未能解决你的问题,请参考以下文章
Oracle PL/SQL:如何从 VARRAY 的 REF 中进行 DEREF?