所有
这是我试图完成的简化版本。我没有声明自己的类型,而是使用了dbms_sql包中的Number_Table类型。 首先,我创建了一个简单的测试表:
CREATE TABLE collect_test(id NUMBER(38), other_info VARCHAR2(5));
然后,用少量数据填充表格:
INSERT INTO collect_test
SELECT rownum, chr(rownum+60)
FROM dual
CONNECT BY rownum <= 10;
最后,我尝试使用PL / SQL在集合中选择一些行,然后使用该集合从表中删除行:
DECLARE
l_tIDList DBMS_SQL.Number_Table;
BEGIN
SELECT ct.id
BULK COLLECT INTO l_tIDList
FROM collect_test ct
WHERE mod(ct.id, 2) = 0;
DELETE FROM (SELECT ct.id
FROM collect_test ct
INNER JOIN table(l_tIDList) ids ON ct.id = ids.column_value);
ROLLBACK;
END;
/
但是,当我运行此PL / SQL块时,我收到以下错误:
ORA-06550: line 11, column 33:
PLS-00382: expression is of wrong type
ORA-06550: line 11, column 27:
PL/SQL: ORA-22905: cannot access rows from a non-nested table item
ORA-06550: line 9, column 3: PL/SQL: SQL Statement ignored
在我发现的所有其他问题/文章中,似乎编码器要么尝试使用本地类型,要么忘记使用BULK COLLECT。我感谢你提出的任何建议。
N.B。:我意识到我可以使用单个DELETE语句来执行此特定功能。我的实际情况更复杂,无法用一个语句完成。
答案 0 :(得分:0)
我用光标尝试了这个,它对我有用。请尝试如下。
DECLARE
l_tIDList DBMS_SQL.Number_Table;
CURSOR c
IS
SELECT ct.id FROM collect_test ct WHERE mod(ct.id, 2) = 0;
BEGIN
OPEN c;
LOOP
FETCH c bulk collect INTO l_tIDList;
forall i IN 1 .. l_tIDList.count
DELETE FROM collect_test t WHERE t.id = l_tIDList(i);
EXIT
WHEN c%notfound;
END LOOP;
COMMIT;
CLOSE c;
END ;
/
答案 1 :(得分:0)
虽然目前还不清楚你要完成什么,但你的pl / sql块有两个错误。
您可以对集合的变量使用TABLE()
函数
模式中定义的类型,而不是本地定义的类型
运行DML(删除)语句的方式是错误的,它会抛出错误“
ORA-22841:不支持PL / SQL集合上的DML。
因此,在模式中创建一个集合TYPE
,并在PL / SQL块中声明该类型的集合,并为删除使用IN
条件
CREATE OR REPLACE TYPE idlisttable as TABLE OF NUMBER;
DECLARE l_tidlist idlisttable;
BEGIN
SELECT ct.id BULK collect
INTO l_tidlist
FROM collect_test ct
WHERE MOD(ct.id, 2) = 0;
DELETE
FROM collect_test ct
WHERE ct.id IN (
SELECT ids.column_value
FROM TABLE (l_tidlist) ids
);
ROLLBACK;
END;
/
`