前提
今天在編寫業務的存儲過程時,需要使用到AND條件的拼接,而根據業務邏輯要求存在多達9種排列組合
以往只有兩三種排列組合時,我會選擇直接使用了PL/SQL的IF語句分支進行判斷,這樣更加簡潔明了,易於理解
在存儲過程中使用動態SQL的好處:
- 提高SQL的復用性,減少重復編寫SQL
- 根據業務邏輯進行條件拼接,減少排列組合帶來的代碼冗余
- 后續需要進行擴展時,更加方便和可維護
問題
使用參數游標,即: [參數名] OUT sys_refcursor
游標最基本的使用方式,PL/SQL如下:
OPEN myCur FOR
SELECT * FROM person;
那如果需要在存儲過程中使用輸出游標結合動態sql拼接,該如何做呢?
解決方法
例子如下:
DECLARE
p_person_id varchar(255);
p_person_phone varchar(255);
SQL_Text varchar2(32760) := 'SELECT * FROM person WHERE 1 = 1 ';
myCur sys_refcursor;
BEGIN
IF p_person_id IS NOT NULL THEN
SQL_Text := SQL_Text || ' AND person_id = '' ' || p_person_id || ''' ';
END IF;
IF p_person_phone IS NOT NULL THEN
SQL_Text := SQL_Text || ' AND person_phone = '' ' || p_person_phone || ''' ';
END IF;
dbms_output.put_line(SQL_Text);
OPEN myCur FOR SQL_Text;
END;
注意事項
- 使用參數游標時,OPEN-FOR 可以直接使用來代替 EXECUTE IMMEDIATE
- 動態SQL(SQL_Text)的長度是有限制的,保證自己的動態SQL拼接完畢之后長度不會溢出(網上也有其他方式以支持更長長度,請自行查詢)
- WHERE 1 = 1 用於方便拼接條件,並且注意空格的合理應用
- 開發時使用輸出語句 dbms_output.put_line(SQL_Text) 打印一下動態SQL,查看語句是否正確
