有時,我們需要在存儲過程或函數中根據條件拼湊一些sql字符串語句,然后再執行拼湊后的sql字符串,如何做到呢?
參考以下代碼:
FUNCTION CALCULATE_TARGET_SCORE (CUR_MONTH IN NVARCHAR2) RETURN NCLOB IS PRAGMA AUTONOMOUS_TRANSACTION; TVALUE_SQL VARCHAR2 (2000); --查詢目標值的sql(不能把類型聲明為NVARCHAR2) RESULT_STR NCLOB; KPI_VALUE NVARCHAR2 (200); CUR_MONTH_BILL_ID NUMBER (19); --固話單ID BEGIN --獲得當前固話單 SELECT MAX (ID) INTO CUR_MONTH_BILL_ID FROM GP_MONTH_BILL WHERE MONTH = CUR_MONTH AND IS_USE = 1; --循環獲得每個明細的完成值sql IF CUR_MONTH_BILL_ID > 0 --區縣指標 THEN TVALUE_SQL := 'SELECT TO_CHAR(' || CUR_ROW.MAIN_FIELD || ') FROM ' || CUR_ROW.END_TABLE || '_' || CUR_MONTH || ' WHERE TO_CHAR(DISTRICT_ID)=''' || CUR_ROW.E_DISTRICT_ID || ''''; ELSE --客戶經理指標 TVALUE_SQL := 'SELECT TO_CHAR(' || CUR_ROW.MAIN_FIELD || ') FROM ' || CUR_ROW.END_TABLE || '_' || CUR_MONTH || ' WHERE MANAGER_NO=''' || CUR_ROW.MANAGER_NO || ''''; END IF; BEGIN EXECUTE IMMEDIATE TVALUE_SQL INTO KPI_VALUE; --執行sql,得到完成值kpi_value EXCEPTION WHEN OTHERS THEN RESULT_STR := RESULT_STR || '<br/> sql執行錯誤:' || TVALUE_SQL || ' INTO KPI_VALUE'; END;
--一些sql邏輯,含dml語句
COMMIT; END;
關鍵語句:EXECUTE IMMEDIATE TVALUE_SQL INTO KPI_VALUE;
本項目涉及到的知識點:
1)在該示例中,需要把查詢的值動態賦值給一個變量。注意變量的賦值不是在sql字符串中去拼湊,而是在執行sql字符串時在末尾加入 INTO VAL
2)如果要通過查詢方式調用函數,同時函數中包含DML 語句時,在聲明函數需要加入 PRAGMA AUTONOMOUS_TRANSACTION;
查詢調用函數示例: SELECT YOUR_FUN(VAL1,VAL2...) FROM DUAL;
3)如果函數聲明中含有 PRAGMA AUTONOMOUS_TRANSACTION; 則在函數結尾加入commit 或 rollback
關聯閱讀:ORA-14551: 無法在查詢中執行 DML 操作
關於EXECUTE IMMEDIATE的擴展閱讀:
execute immediate的簡單用法(oracle)
把一個查詢結果集插入到臨時表,需要用變量寫法,參考如下:
declare l_sal pls_integer := 2000; begin execute immediate 'insert into temp(empno, ename) ' || ' select empno, ename from emp ' || ' where sal > :1' using l_sal; commit; end;