如何批量收集到子查询中的 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 类型的主要内容,如果未能解决你的问题,请参考以下文章