0

我有下表,基于它的两种类型,以及从该表中读取的函数:

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

所以我必须将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

如何将行插入tblmyTable

4

1 回答 1

2

由于您不能使用本地定义的嵌套表作为TABLE函数的参数,也许您会考虑使用FORALL批量插入?我看到您使用的是 Oracle 11g,因此您将能够访问myRowType. 然后,您将使用以下内容替换您INSERT的 PL/SQL 块:

FORALL v_i IN tbl.FIRST..tbl.LAST
  INSERT INTO myTable VALUES (sys_guid(), tbl(v_i).name, tbl(v_i).entityid);

我推荐 Tim Hall 的这篇很棒的文章:BULK COLLECT & FORALL

于 2013-10-31T13:45:13.907 回答