2015-07-20 86 views
0

未經測試的水域,我試圖找到一種方法來緩解事情。而不是在PL-SQL中的遊標中嵌套選擇。我想在遊標中創建一個案例。由於遊標可以有不同的參數,我需要相應地分類。在光標下的情況

這可能嗎?我的代碼看起來像這樣。很容易閱讀ao_in是Inparam。

PROCEDURE theProcedure (ao_in IN VARCHAR2) 

CURSOR order_cur 
    IS 
Case when ao_in = 'NIEC' 
    then   
     SELECT t1.nr, t1.status$nr 
     FROM [email protected]_DBLINK t1 
     WHERE  t1.status$nr IN (3, 6) 
     AND ao_in = 
        DECODE (ao_in, 'NIEC', ao_in, get_ehorder_ao (t1.nr)) 
       AND t1.nr = DECODE (order_in, NULL, t1.nr, order_in) 
    ORDER BY t1.skapad_dat ASC; 

    when ao_in = 'DSSP' then 
    SELECT t1.nr, t1.status$nr 
     FROM [email protected]_DBLINK t1 
     WHERE  t1.status$nr IN (3, 6) 
     AND ao_in = 
        DECODE (ao_in, 'DSSP', ao_in, get_ehorder_ao (t1.nr)) 
       AND t1.nr = DECODE (order_in, NULL, t1.nr, order_in) 
    ORDER BY t1.skapad_dat ASC; 
    when ao_in = 'ALLA' 

    SELECT t1.nr, t1.status$nr 
     FROM [email protected]_DBLINK t1 
     WHERE  t1.status$nr IN (3, 6) 
     AND ao_in = 
        DECODE (ao_in, 'ALLA', ao_in, get_ehorder_ao (t1.nr)) 
       AND t1.nr = DECODE (order_in, NULL, t1.nr, order_in) 
    ORDER BY t1.skapad_dat ASC; 
    end 
+0

ao_in是對過程的參數。它也是桌子上的一列嗎?因爲如果不是,我不會看不到你想要做什麼的邏輯。 – Rene

+2

你不能使用'case'來運行不同的語句。 (SQL)情況只能用於返回單個(列)值。你需要三個光標,然後當你打開光標時,你需要檢查參數並打開正確的參數。 –

+0

@ahorsewithnoname聯盟所有和檢查參數值的條件是什麼?-) –

回答

1

你想要可以與OPEN-FOR語句來完成,像這樣的內容:

PROCEDURE theProcedure (ao_in IN VARCHAR2) 

    TYPE t_cur IS REF CURSOR; 
    order_cur t_cur; 

begin 
    Case when ao_in = 'NIEC' 
     then 
     open order_cur for 
       SELECT t1.nr, t1.status$nr 
       FROM [email protected]_DBLINK t1 
       WHERE  t1.status$nr IN (3, 6) 
       AND ao_in = 'NIEC' 
       AND t1.nr = DECODE (order_in, NULL, t1.nr, order_in) 
      ORDER BY t1.skapad_dat ASC; 

     when ao_in = 'DSSP' then 
     open order_cur for 
       SELECT t1.nr, t1.status$nr 
       FROM [email protected]_DBLINK t1 
       WHERE  t1.status$nr IN (3, 6) 
       AND ao_in = 'DSSP' 
       AND t1.nr = DECODE (order_in, NULL, t1.nr, order_in) 
      ORDER BY t1.skapad_dat ASC; 
     when ao_in = 'ALLA' 
     open order_cur for 
      SELECT t1.nr, t1.status$nr 
      FROM [email protected]_DBLINK t1 
      WHERE  t1.status$nr IN (3, 6) 
       AND ao_in ='ALLA' 
       AND t1.nr = DECODE (order_in, NULL, t1.nr, order_in) 
     ORDER BY t1.skapad_dat ASC; 
    end; 
end; 

注意的ao_in參數解碼評價是沒有必要的,因爲已經在case語句進行評估。 我認爲order_in是在原始代碼的某個地方聲明的,爲了簡化不在這裏發佈,否則應該聲明。

0

我們來分析一下你的選擇:無論案件表達的

SELECT t1.nr, t1.status$nr 
    FROM [email protected]_DBLINK t1 
    WHERE  t1.status$nr IN (3, 6) 
    AND ao_in = 
       DECODE (ao_in, 'DSSP', ao_in, get_ehorder_ao (t1.nr)) 
      AND t1.nr = DECODE (order_in, NULL, t1.nr, order_in) 
ORDER BY t1.skapad_dat ASC; 

條件ao_in = DECODE...始終爲真。
條件t1.nr = DECODE...可以重寫爲t1.nr = NVL(order_in, t1.nr),但是order_in的定義在哪裏?
結合:你的情況沒有任何意義(並且不能用這種方式)。

如果要根據參數運行不同的select語句,請對where和union使用where條件來處理所有這些select語句。

1

假設你在eh_order_t @ ngext_dblink表有一個名爲「ao_in」專欄中,我覺得你是什麼這樣的事情後:

PROCEDURE theProcedure (p_ao_in IN VARCHAR2) 
IS 
    CURSOR order_cur 
    IS 
    SELECT t1.nr, 
      t1.status$nr 
    FROM [email protected]_DBLINK t1 
    WHERE t1.status$nr IN (3, 6) 
    AND (p_ao_in in ('NIEC', 'DSSP', 'ALLA') 
      OR 
      (p_ao_in not in ('NIEC', 'DSSP', 'ALLA') and ao_in = get_ehorder_ao (t1.nr))) 
    AND t1.nr = COALESCE(order_in, t1.nr) 
    ORDER BY t1.skapad_dat ASC; 
BEGIN 
    FOR order_rec in order_cur 
    LOOP 
    -- do the things 
    END LOOP; 
END; 
/

或者,你可以有兩個光標,一個選擇一切,並在ao_in列上過濾,然後根據傳入的參數調用相關的一個。我相信Oracle應該能夠根據傳入的參數優化上述組合遊標,但是如果找到它不能或想要確保,將光標分成兩個單獨的將有助於優化器。

在PL/SQL中,不應該在遊標中使用相同的參數或變量名,這很重要,因爲優化器可能會變得非常混亂,並且很可能會使您的and column_name = variable_of_same_name_as_column_name表示and column_name = column_name,可能不是你想要的!

ETA:如果循環中的工作是DML,可能您可能完全不用光標,只需要一個DML語句。這將是最好的使用場景,因爲逐行處理不是PL/SQL中最快的事情。基於集合的處理ftw! * {:-)

0

您可以使用參數光標link

例如:

CREATE TABLE tbl 
(ID int, name varchar(50)); 

INSERT INTO tbl select 1, '0011' from dual; 
INSERT INTO tbl select 1, '0012' from dual; 
INSERT INTO tbl select 1, '0013' from dual; 
INSERT INTO tbl select 1, '0014' from dual; 
INSERT INTO tbl select 2, '0015' from dual; 
INSERT INTO tbl select 2, '0016' from dual; 
INSERT INTO tbl select 2, '0017' from dual; 


set serveroutput on 
declare 
    CURSOR para_cur(num NUMBER) IS select name from tbl where id = num; 
begin 
    dbms_output.put_line('for id = 1'); 
    FOR idx in para_cur(1) LOOP 
     dbms_output.put_line(idx.name); 
    end loop; 

    dbms_output.put_line('for id = 2'); 
    FOR idx in para_cur(2) LOOP 
     dbms_output.put_line(idx.name); 
    end loop; 
end; 

出認沽:

anonymous block completed 
for id = 1 
0011 
0012 
0013 
0014 
for id = 2 
0015 
0016 
0017