Sql 多次调用oracle内联函数

Sql 多次调用oracle内联函数,sql,oracle,Sql,Oracle,当通过内联select语句调用函数时,当函数返回自定义类型时,Oracle执行的函数似乎等于参数数+1。当select作为CTA或insert/select包含时,似乎会发生这种情况 以前有人见过这个吗?这是甲骨文的错误吗?我希望该函数在表中每行调用一次 --Inline function gets called for the number of arguments +1 --drop table t create table t( id number, l_blob blob );

当通过内联select语句调用函数时,当函数返回自定义类型时,Oracle执行的函数似乎等于参数数+1。当select作为CTA或insert/select包含时,似乎会发生这种情况

以前有人见过这个吗?这是甲骨文的错误吗?我希望该函数在表中每行调用一次

--Inline function gets called for the number of arguments +1

--drop table t
create table t(
  id number,
  l_blob blob
);


insert into t values(1, utl_raw.cast_to_raw('SampleString'));
COMMIT;

create table tmp_ts (c1 timestamp); 

create or replace type test_type as object(
              c1         varchar2(32)
              ,c2  varchar2(32)
        );
/

create or replace FUNCTION test_function (p_blob blob, p_date date)
RETURN test_type
IS
BEGIN

--This could also be a DBMS_OUTPUT.PUT_LINE statement
insert into tmp_ts VALUES (systimestamp);

return test_type(null,null);

END test_function;
/

--0
select count(*) from tmp_ts;

--Call function on 1 row table - function should just insert 1 row into tmp_ts
create table tst_table as
select test_function(l_blob, '25-JAN-09') as c1
from t;

--it actually inserts 3
select count(*) from tmp_ts;
增加类型的参数调用会增加函数执行时间的示例


--同样的例子有更多的争论-这里有6个争论
非常感谢您的帮助/反馈。

首先:您甚至可以在SELECT语句中调用的函数中执行DML,这是一个错误。这应该引起一个例外

否则,Oracle绝对不能保证SQL Select中函数的执行频率,它可以是每行一次,每行十次,或者整个查询只执行一次(带缓存)——因此,无论调用的频率如何,这都符合规范

在这种特殊情况下,它将为返回类型的每个属性调用函数,因为oracle不会将对象类型作为一个内存结构插入,而是像使用具有多列的表一样使用该函数,并按如下方式分别读取每列:

INSERT VALUES ( myFunc(x).attribute1, myFunc(x).attribute2 );
重要的部分:在SQL语句中使用函数时,千万不要假设函数的调用频率!!!在任何时候,优化器都可以再次调用该函数,可能是为了采样或缓存


首选解决方案:流水线函数-可以像表一样调用流水线函数,并且只能调用一次。您可以传入函数用于输入处理的游标,并执行整个数据转换和日志记录以及函数中的所有操作。

有人应该写下答案,即使这是上面oracle社区线程的想法。。。
INSERT VALUES ( myFunc(x).attribute1, myFunc(x).attribute2 );