Oracle 在存儲過程或函數中執行字符串sql


有時,我們需要在存儲過程或函數中根據條件拼湊一些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)

ORACLE EXECUTE IMMEDIATE 小結

把一個查詢結果集插入到臨時表,需要用變量寫法,參考如下:

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;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM