我有下表,基于它的两种类型,以及从该表中读取的函数:
CREATE TABLE myTable (
ID RAW(16) NULL,
NAME NVARCHAR2(200) NULL,
ENTITYID RAW(16) NOT NULL
);
CREATE TYPE myRowType AS OBJECT (
NAME NVARCHAR2(200),
ENTITYID RAW(16)
);
CREATE TYPE myTableType IS TABLE OF myRowType;
CREATE FUNCTION myFunction(...) RETURN myTableType ...
如您所见,myRowType
类型与myTable
类似,但不完全相同。
我的目标是根据myTable
的结果将行插入myFunction
。
天真的方法就是写:
INSERT INTO myTable(ID, NAME, ENTITYID)
SELECT sys_guid(), NAME, ENTITYID
FROM TABLE(myFunction(...));
但是,由于myFunction
从myTable
读取,因此会导致以下错误:
ORA-04091: table myTable is mutating, trigger/function may not see it
所以我必须从insert语句中拆分myFunction
调用。我试过这样的话:
DECLARE
tbl myTableType;
BEGIN
SELECT myRowType(x.NAME, x.ENTITYID)
BULK COLLECT INTO tbl
FROM TABLE(myFunction(...)) x;
INSERT INTO myTable
(ID, NAME, ENTITYID)
SELECT sys_guid(), x.NAME, x.ENTITYID
FROM tbl x;
END;
但是在这里,Oracle似乎并不理解FROM tbl
子句。它显示错误
ORA-00942: table or view does not exist
如何将tbl
中的行插入myTable
?
答案 0 :(得分:2)
由于您不能使用本地定义的嵌套表作为TABLE
函数的参数,您可以考虑使用FORALL
批量插入吗?我发现您使用的是Oracle 11g,因此您可以访问myRowType
的字段。然后,您将用PL / SQL块替换INSERT
:
FORALL v_i IN tbl.FIRST..tbl.LAST
INSERT INTO myTable VALUES (sys_guid(), tbl(v_i).name, tbl(v_i).entityid);
我推荐蒂姆·霍尔的这篇精彩文章:BULK COLLECT & FORALL