如何批量收集到子查询中的 UDT 类型

Posted

技术标签:

【中文标题】如何批量收集到子查询中的 UDT 类型【英文标题】:How to bulk collect into a Type where UDT in subquery 【发布时间】:2019-02-05 18:31:17 【问题描述】:

我正在尝试创建一个值集合,我计划针对这些值运行 FORALL DELETE FROM [table]。 当我在子查询中有一个 UDT 时,似乎没有任何东西被批量收集到集合中。

这似乎不起作用。

SELECT ATTR1
BULK COLLECT INTO tmpTBL1
FROM Table1
WHERE ATTR1 NOT IN (SELECT ATTR1 FROM TABLE(tmpPList)); --99% sure problem is here.

还确认对象类型中的列大小与 Person 表中的大小相同。 (思想填充可能是个问题。)

对象类型

CREATE OR REPLACE type dbo.P_REC AS OBJECT
(
    ATTR1    VARCHAR2(64 BYTE),
    ATTR2    VARCHAR2(128 BYTE),
    ATTR3    VARCHAR2(128 BYTE),
    ATTR4    VARCHAR2(128 BYTE)
);

集合类型

CREATE OR REPLACE type dbo.P_REC_LIST is table of P_REC;

存储过程

PROCEDURE Get_PRecList(tmpPList IN P_REC_LIST,
               resultCursor out sys_refcursor)
IS

TYPE CNsTable IS TABLE OF PERSON.ATTR1%TYPE INDEX BY PLS_INTEGER;
TYPE TmpTable IS TABLE OF P_REC INDEX BY PLS_INTEGER;

tmpTBL1        CNsTable;
Collection1    TmpTable;

BEGIN

    IF tmpPList.count > 0 THEN

    SELECT ATTR1
    BULK COLLECT INTO tmpTBL1
    FROM Table1
    WHERE ATTR1 NOT IN (SELECT ATTR1 FROM TABLE(tmpPList)); --99% sure problem is here.

    FOR indx IN 1 .. tmpTBL1.COUNT
    LOOP
        Collection1(Collection1.COUNT + 1) := tmpPList(indx);
    END LOOP;

    IF Collection1.COUNT > 0 THEN
        FORALL ind IN 1 .. Collection1.COUNT
            DELETE 
            FROM PERSON
            WHERE ATTR1 = Collection1(ind).ATTR1;
    END IF;

模拟表数据

tmpPList 
 __________________________________________
|__attr1__||__attr2__||__attr3__||__attr4__|
   jdoe       John       Doe        abcd
   fmac      Frank       Mac        efgh
   wgab      Wayne       Gab        ijkl

Table1
 __________________________________________
|__attr1__||__attr2__||__attr3__||__attr4__|
   jdoe       John       Doe        abcd
   fmac       Frank      Mac        efgh
   wgab       Wayne      Gab        ijkl
   mkell      Mike       Kell       mnop

Table2
 __________________________________________
|__attr1__||__attr2__||__attr3__||__attr4__|
   mdoe       Mary       Doe        abcd
   jmac       John       Mac        efgh
   mgab       Mitch      Gab        ijkl
   mkell      Mike       Kell       mnop

tmpTBL1
 _________
|__attr1__|
  mkell

Collection1
 __________________________________________
|__attr1__||__attr2__||__attr3__||__attr4__|
   mkell      Mike       Kell       mnop

Before delete - Person
 __________________________________________
|__attr1__||__attr2__||__attr3__||__attr4__|
   jdoe       John       Doe        abcd
   fmac       Frank      Mac        efgh
   wgab       Wayne      Gab        ijkl
   mkell      Mike       Kell       mnop

After delete - Person
 __________________________________________
|__attr1__||__attr2__||__attr3__||__attr4__|
   jdoe       John       Doe        abcd
   fmac       Frank      Mac        efgh
   wgab       Wayne      Gab        ijkl

当我使用 TABLE(tmpPList) 时,tmpTBL1 没有填充值。 我希望从人身上删除记录。 试图找到在 PERSON 中存在但在 tmpPList 中不存在的 ATTR1。

更新: 使用:Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit

【问题讨论】:

【参考方案1】:

我的问题不在这里。

SELECT ATTR1
BULK COLLECT INTO tmpTBL1
FROM Table1
WHERE ATTR1 NOT IN (SELECT ATTR1 FROM TABLE(tmpPList));

但是在这里。不需要整个 for 循环,没有它,FORALL 语句也能正常工作。

FOR indx IN 1 .. tmpTBL1.COUNT
LOOP
    Collection1(Collection1.COUNT + 1) := tmpPList(indx); 
END LOOP;

【讨论】:

以上是关于如何批量收集到子查询中的 UDT 类型的主要内容,如果未能解决你的问题,请参考以下文章

BigQuery 将新列添加到子查询中的嵌套 STRUCT

sql查询到子查询的laravel查询

访问报表传递参数到子报表查询

将带有数据的查询从父表单中的组合框输入到子表单中的列表框

如何在子查询中使用 select 中的值?

从查询到子查询的组中未选择的值