2012-12-14 55 views
2
create or replace 
PROCEDURE get_txn_by_account_id(
p_ACCOUNT_ID IN txn.ACCOUNT_ID%TYPE DEFAULT NULL 
) 

IS 

BEGIN 
FOR x IN (SELECT * FROM txn where account_id=p_ACCOUNT_ID) 
LOOP 
    dbms_output.put_line(x.txn_ID || ', ' || x.txn_VER_NB); 

END LOOP; 
END get_txn_by_account_id; 

我的存儲過程根據一個輸入作爲搜索條件發出一個select並輸出搜索結果。我的輸入是 ACCOUNT_ID。我想添加4個額外的輸入參數(param_a,param_b,param_c,param_d) - 其中至少兩個將是 可選。Oracle存儲過程 - 根據可選參數動態生成select語句

所以我可能會改變我的存儲過程的聲明像

PROCEDURE get_txn_by_account_id(
p_ACCOUNT_ID IN txn.ACCOUNT_ID%TYPE DEFAULT NULL, 
p_PARAM_A IN txn.PARAM_A%TYPE DEFAULT NULL, 
p_PARAM_B IN txn.PARAM_B%TYPE DEFAULT NULL, 
p_PARAM_C IN txn.PARAM_C%TYPE DEFAULT NULL, 
p_PARAM_D IN txn.PARAM_D%TYPE DEFAULT NULL 
) 

所以我的選擇可能有不同數量的查詢PARAMS基於傳遞給存儲 PROC什麼可選PARAMS。

例如,

FOR x IN (SELECT * FROM txn where account_id=p_ACCOUNT_ID, param_a=p_PARAM_A, param_b=p_PARAM_B, param_c=p_PARAM_C, param_d=p_PARAM_D) 
FOR x IN (SELECT * FROM txn where account_id=p_ACCOUNT_ID, param_a=p_PARAM_A, param_c=p_PARAM_C, param_d=p_PARAM_D) 
FOR x IN (SELECT * FROM txn where account_id=p_ACCOUNT_ID, param_a=p_PARAM_A, param_b=p_PARAM_B, param_d=p_PARAM_D) 

FOR x IN (SELECT * FROM txn where account_id=p_ACCOUNT_ID, param_a=p_PARAM_A, param_b=p_PARAM_B) 

我遇到的麻煩 - 如何讓基於什麼SELECT語句改變我的代碼存儲過程可選參數通過 傳遞給存儲過程 - 可能是一個字符串構建器,它根據傳遞給proc的可選參數構建查詢語句, ,然後在查詢中使用結果字符串?我不確定這是否可能。當然這是一個普遍的問題 - 任何人有任何建議嗎?謝謝!

+0

爲什麼'p_ACCOUNT_ID'是可選的?或者換一種說法,如果沒有提供'p_ACCOUNT_ID',你想返回什麼? – 2012-12-14 17:59:25

+0

在這種情況下,我會返回一個空集 – user619804

回答

3
FOR x IN (SELECT * 
      FROM txn 
      WHERE account_id=p_ACCOUNT_ID 
      AND (p_PARAM_A is null or param_a=p_PARAM_A) 
      AND (p_PARAM_B is null or param_b=p_PARAM_B) 
      AND (p_PARAM_C is null or param_c=p_PARAM_C) 
      AND (p_PARAM_D is null or param_d=p_PARAM_D)) 
+0

事情是 - 例如,如果PARAM_A沒有傳遞到存儲過程 - 我不一定要搜索PARAM_A作爲連接的一部分是空的,我' d只是不包含PARAM_A作爲查詢參數。 – user619804

+0

讓優化器處理:'p_PARAM_A的結果爲空'在編譯時是已知的。 – 2012-12-14 19:10:30

+0

還是我誤解了你:如果你使用我的查詢,你是*不*搜索'PARAM_A is null'作爲連接的一部分,你正在搜索'p_PARAM_A is null',在這種情況下,編譯時間。 – 2012-12-14 19:13:22

1

您可以使用下面的技巧:

select * from FOO 
where 
    COLUMN_1 = nvl(pParam1, COLUMN_1) 
    and COLUMN_2 = nvl(pParam2, COLUMN_2) 
    and ... 

這確保瞭如果pParam1null,你的條件計算結果始終爲true。等等。