我在ORACLE 11g上使用SQL插入table1
,同时触发插入table3
的存储函数。存储的函数没有触发,我怀疑这是因为ORACLE优化器意识到插入table1
不需要存储的函数,所以它忽略它们?
有没有办法请求oracle不优化查询或是否有更好的解决方案。
示例代码:
INSERT INTO table1 (col1)
SELECT A.col1
FROM (SELECT col1, storedFunction(col2),storedFunction(col3),storedFunction(col4)
FROM table2) A
答案 0 :(得分:2)
您可以让存储过程返回NULL
并使用以下内容:
INSERT INTO table1 (col1)
SELECT NVL( col1, storedProcedure(col2) )
FROM table2
NVL
总是评估这两个参数,即使第一个参数不为空。
我不确定我是否会对这种黑客感到满意......
答案 1 :(得分:1)
鉴于您的storedFunction
作为自治交易工作,并且您正在处理> 1亿行,您可能会遇到严重的性能问题。如果可能的话,我会重新考虑整个战略。报废它。重新开始。
选项1
如果无法做到这一点,最好的办法是执行bulk collect
次提取(有限制)以检索col1
和col2
,明确调用storedFunction
对于每行col2
,然后bulk insert
进入table1
。这应该有希望最小化来自table2
的读取的I / O并写入table1
。你打算通过拨打storedFunction
给吹笛者付钱。
选项2 将您的函数包含在另一个具有您想要的行为的函数中。你没有提到类型,但我假设VARCHAR2。当然,您可以根据需要进行调整。 请原谅语法错误,因为我没有方便的Oracle数据库。
CREATE FUNCTION MYFUNC(col1 IN VARCHAR2, col2 IN VARCHAR2) RETURN VARCHAR2
AS
v_dummy VARCHAR2(100);
BEGIN
v_dummy := storedFunction(col2); --Call stored function
return col1; --return col 1 unchanged
END;
然后你可以按如下方式进行插入:
INSERT INTO table1 (col1)
SELECT MYFUNC(A.col1, A.col2)
FROM table2 A;
答案 2 :(得分:1)
SQL解决方案是使子查询成为临时表,并使用子查询中的/*+ MATERIALIZE */
提示强制Oracle评估存储的函数。
e.g。
INSERT INTO table1 (col1)
WITH temp_table AS (/*+ MATERIALIZE */ SELECT col1, storedFunction(col2),storedFunction(col3),storedFunction(col4)
FROM table2)
SELECT col1
FROM temp_table