2010-07-27 61 views
2

Im Oracle新增了对游标的新功能。我有一块包含在变量中的SQL。我想用这个sql打开一个游标。我该怎么做呢?看起来很简单,但我发现所有的例子都只有在“open cursor_name for”语句下键入的sql。Oracle PLSQL从一个变量中设置游标

这里是我想什么来运行(假设我有可变v_sql与我的SQL查询):

open my_cursor for v_sql; 

甲骨文犯规这样虽然。我也试过

open my_cursor for 
    execute immediate v_sql; 

请帮忙。

+1

你[冒着注射攻击的危险](http://xkcd.com/327/)... – 2010-07-27 19:04:34

+0

冒着生命危险,我的眼睛。诱人。 – 2010-07-27 21:18:18

+2

@OMGPonies,@AdamMusch - 如果可以将整个字符串传递给'v_sql',SQL注入只是一个风险。在程序中组装SQL查询是完全安全的。 – APC 2010-07-28 05:18:31

回答

5

您需要将其声明为引用游标,然后将其打开以供您的SQL语句使用。请看下面的例子。当然,这是假设你没有任何输入绑定到你的SQL。

sql> ed 
Wrote file afiedt.buf 

    1 declare 
    2  c1 sys_refcursor; 
    3  v_empno number; 
    4  v_ename varchar2(30); 
    5 begin 
    6 open c1 for 'select empno, ename from emp'; 
    7 loop 
    8  fetch c1 into v_empno, v_ename; 
    9  dbms_output.put_line(v_empno || '--' || v_ename); 
10  exit when c1%notfound; 
11 end loop; 
12 close c1; 
13* end; 
sql>/
7369--SMITH 
7499--ALLEN 
7521--WARD 
7566--JONES 
7654--MARTIN 
7698--BLAKE 
7782--CLARK 
7788--SCOTT 
7839--KING 
7844--TURNER 
7876--ADAMS 
7900--JAMES 
7902--FORD 
7934--MILLER 
7934--MILLER 

检查此链接... http://download.oracle.com/docs/cd/B14117_01/appdev.101/b10807/11_dynam.htm#i13057

1

只要v_sql是VARCHAR并且my_cursor被声明为REF CURSOR,那么您拥有的第一个代码段就可以正常工作。然后,您可以像使用静态游标那样从中获取。

但是正如OMG Ponies所说的,你必须小心你的SQL来自哪里。

+0

谢谢丹。你是对的。我的问题是,我定义了我的参考游标,如下所示: TYPE ccproc_record_csr IS REF CURSOR RETURN ccproc_record; ccproc_record是我定义的类型,我正在返回。我从同事代码中复制了这种代码风格。因为我可以只返回一个游标,我想我很担心为什么有人会费心去定义查询返回的内容?看起来像是额外的工作。 – Eddieb 2010-07-29 13:13:17

+0

由于某些原因,PL/SQL不允许直接将变量定义为引用游标。你不能将变量声明为'my_cursor ref cursor;'。但从Oracle 9i开始,有一种名为'SYS_REFCURSOR'的内置类型,您可以使用它来代替每次声明自己的类型。早于9i的代码仍旧具有旧式的风格。 – Dan 2010-07-29 14:13:28

0

OMG小马是完全正确的,

,但这里只是用不同的方式做同样的事情

Var X Refcursor; 
Begin 
Open :X For 
    Select 1 Num, 'b' Co 
    From Dual 
    Union 
    Select 2 Num, 'c' Co 
    From Dual; 

end; 

/
print x; 

时注意你在Oracle中做任何事情就像打开游标,或者你不需要在BEGIN/END之内,你不能简单地做:

Var X Refcursor; 
Open X For 
    Select 1 Num, 'b' Co 
    From Dual 
    Union 
    Select 2 Num, 'c' Co 
    From Dual; 

这不行!你必须在BEGIN/END块内封闭打开的游标(无论是一个anonomous块或程序...)

Create or replace Procedure Ccc(X Out sys_Refcursor) 
As 
begin 
Open X For 
    Select 1 Num, 'b' Co 
    From Dual 
    Union 
    Select 2 Num, 'c' Co 
    From Dual; 
End Ccc; 
/

Var X Refcursor; 
Begin 
Ccc(:X); 
End; 
/
print x; 

注意:X在anonomous块的开始/结束是告诉SQL引擎您正在使用在块外部创建的变量。在packages/procs中是没有必要的。