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)
把一个查询结果集插入到临时表,需要用变量写法,参考如下:
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;