2

我在 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  
4

3 回答 3

2

您可以让您的存储过程返回NULL并使用以下内容:

INSERT INTO table1 (col1)
SELECT NVL( col1, storedProcedure(col2) )
FROM table2

NVL始终评估两个参数,即使第一个参数不为空。

我不确定我是否会对这个黑客感到满意......

于 2012-07-18T14:17:37.337 回答
1

鉴于您storedFunction作为一个自治事务工作,并且您正在处理超过 1 亿行,您可能会遇到严重的性能问题。如果可能的话,我会重新考虑整个策略。报废它。重来。

选项1

如果这不可能,最好的办法是执行bulk collect提取(有限制)以检索col1col2,显式调用storedFunction每一行的col2,然后bulk insert进入table1。这应该有望最大限度地减少读取table2和写入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;  
于 2012-07-18T15:32:44.600 回答
1

SQL 的解决方案是将子查询做成临时表,并使用/*+ MATERIALIZE */子查询中的提示来强制 Oracle 对存储的 Functions 进行求值。例如

INSERT INTO table1 (col1)
WITH temp_table AS (/*+ MATERIALIZE */  SELECT col1, storedFunction(col2),storedFunction(col3),storedFunction(col4)
FROM table2) 
SELECT col1
FROM temp_table
于 2012-07-19T13:50:41.967 回答