2010-07-27 42 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中是沒有必要的。