CREATE OR REPLACE PACKAGE test_package
IS
TYPE IDTable IS TABLE OF test_table.id%TYPE;
TYPE RowIDTable IS TABLE OF VARCHAR2(500);
FUNCTION delete_rows (row_ids IN RowIDTable) RETURN IDTable;
END test_package;
/
CREATE OR REPLACE PACKAGE BODY test_package
IS
FUNCTION delete_rows (row_ids IN RowIDTable) RETURN IDTable
IS
ids IDTable;
BEGIN
DELETE FROM test_table
WHERE ROWIDTONCHAR(rowid) IN (SELECT * FROM TABLE(row_ids))
RETURNING id BULK COLLECT INTO ids;
COMMIT;
RETURN ids;
END;
END test_package;
/
使用上述功能时,我不断获得ORA-00902: invalid datatype
。我做错了什么?
错误指向DELETE语句。
答案 0 :(得分:1)
看起来问题是您正在使用的集合类型。因为它是一个包级PL / SQL集合类型。
The ruby-plsql documentation表示它支持PL / SQL记录,但表和varray类型不引用PL / SQL - 表明它们必须是SQL(即模式级)用户定义类型。
即使图中没有Ruby,当运行时始终使用相同的包定义类型时,也会抛出invalid-datatype错误。在12c之前,您根本无法在SQL语句中使用PL / SQL集合,并且在这种情况下它似乎仍然不起作用。
如果从PL / SQL类型更改为模式级类型,则此代码有效,在此示例中为内置varray类型:
CREATE OR REPLACE PACKAGE test_package
IS
TYPE IDTable IS TABLE OF test_table.id%TYPE;
--TYPE RowIDTable IS TABLE OF VARCHAR2(500); —- not used now
FUNCTION delete_rows (row_ids IN sys.odcivarchar2list) RETURN IDTable;
END test_package;
/
CREATE OR REPLACE PACKAGE BODY test_package
IS
FUNCTION delete_rows (row_ids IN sys.odcivarchar2list) RETURN IDTable
IS
ids IDTable;
BEGIN
DELETE FROM test_table
WHERE ROWIDTONCHAR(rowid) IN (SELECT * FROM TABLE(row_ids))
RETURNING id BULK COLLECT INTO ids;
COMMIT;
RETURN ids;
END;
END test_package;
/
您可以使用匿名阻止测试:
declare
ids test_package.idtable;
begin
ids := test_package.delete_rows(sys.odcivarchar2list('ROWID1', 'ROWID2'));
end;
/
不转换表中的每个rowid会更有效,所以你可以这样做:
WHERE rowid IN (SELECT CHARTOROWID(column_value) FROM TABLE(row_ids))
但请记住,rowid并不总是不可变的 - 希望您传入的引用最近足以始终有效。否则,使用主键而不是rowid。
我不知道Ruby,所以不完全确定如何翻译;再次从文档看起来像:
plsql.test_package.delete_rows(['ROWID1','ROWID2'])
...但不确定它将如何处理返回的(PL / SQL)表类型。这可能也需要是模式级表类型。 (如果你想创建自己的类型,你可以创建类型为varrays或嵌套表,这可能是一个好主意。)
答案 1 :(得分:0)
为什么不在RowIDTable上使用TABLE OF ROWID
而不是TABLE OF VARCHAR2(500)
?
像这样:
TYPE RowIDTable IS TABLE OF ROWID;
然后你就不必施放ROWID:
DELETE FROM test_table tbl
WHERE tbl.rowid IN (SELECT column_value FROM TABLE(row_ids))
RETURNING id BULK COLLECT INTO ids;
希望这有帮助。