2014-01-22 89 views
0

我有點困惑PLSQL:在運行時編輯光標

是否有可能在函數/ proc這樣的東西?

CURSOR CR IS 
SELECT 
FROM 
WHERE Y = X 

,後來在體內,改變X值轉換成Z或別的東西,然後重新打開遊標所以它獲取與Y = Z行?

回答

2

有幾個方法可以做到這一點,而不訴諸動態SQL。一種選擇是使用參數光標:

DECLARE 
    nSome_value NUMBER := 666; 

    CURSOR CR(parmSome_value NUMBER) IS 
    SELECT * 
     FROM SOME_TABLE 
     WHERE SOME_COLUMN = parmSome_value; 
BEGIN 
    nSome_value := 123; -- change value of nSome_value 

    OPEN CR(nSome_value); -- pass nSome_value in as the value of the cursor parameter 

    -- Fetch from the cursor, do whatever 

    CLOSE CR; 
END; 

它仍然是靜態SQL,但是通過傳遞參數給你增加了鼠標的可重用性光標。

另一種選擇是使用遊標FOR循環,引用循環的SQL變量:

DECLARE 
    nSome_value NUMBER := 666; 
BEGIN 
    nSome_value := 123; -- change value of nSome_value 

    FOR aRow IN (SELECT * 
       FROM SOME_TABLE 
       WHERE SOME_COLUMN = nSome_value) 
    BEGIN 
    -- Do something useful with the rows returned by the cursor 
    END LOOP; 
END; 

注意,在這些情況下,你不改變SQL - 你只是改變的值查詢中使用的變量或參數。這些方法的一個優點是,與動態生成的SQL不同,它們不容易受到SQL注入攻擊。

分享和享受。

+0

@ ro.nin另一個主要優勢是PL/SQL編譯器可以檢查SQL。 – user272735

+0

非常感謝鮑勃,非常有幫助的建議 –

2

是,嘗試這樣的事情(快速打字所以語法可能不準確)

sql VARCHAR2(255); 
cur REF CURSOR; 
val varchar2(100); 

val := X; 
sql := 'SELECT .. FROM .. WHERE Y = :val'; 

open cur for 
    sql 
    USING val; 

close cur; 
.... 

val := Z; 

open cur for 
    sql 
    USING val; 
+0

謝謝你,所以它的SQL動態 –

+0

@ ro.nin是的,這個工作,但最好不要使用動態sql,除非你真的必須。在這種情況下,更好的選擇是使用參數化光標,如Bob Jarvis所示。 – user272735

0

這也可以通過使用一個子程序等功能,而不是使用一個光標來完成,因爲它

港島線縮短的代碼:

創建或替換功能getashish(DEPT VARCHAR2)返回EMP3作爲

emp5 emp3:= emp3();

str varchar2(300);

開始

STR:從僱員e =「選擇EMP1(e。姓氏,l.city,e.salary)參加部門關於e.department_id = d.department_id上加入位置L的D-

d.location_id = l.location_id其中

d。department_name =:dept';

立即執行 批量收集到emp5 使用部門;

return emp5; 結束;

在這裏你必須創建包括返回類型同比想在返回,然後創建與該對象的表對象:

創建或替換型EMP1作爲對象(L-NAME VARCHAR2(10),城市VARCHAR2( 10),薩爾編號(10));

CREATE OR REPLACE 類型EMP3作爲EMP1的表;