我有一个从 Web 服务调用的包/过程。它返回一个引用器。 我正在尝试优化过滤,因为它实际上有很多过滤选项,下面只是一个小例子。这是为了限制以后使用的记录。
我收到运行时错误: 第 1 行错误 ORA-00902: 无效的数据类型 ORA-06512: 在“MARK.PKG_PRODUCTS”,第 13 行 ORA-06512: 在第 9 行 当它只是一个 select 语句时它有效,但是当我将其更改为插入到表中时,我现在收到此错误。
如下设置和打包
CREATE TABLE PRODUCTS (PRODUCT_ID VARCHAR2(10), VENDOR VARCHAR2(10), ITEM VARCHAR(10));
CREATE TABLE PRODUCT_FILTER (PRODUCT_ID VARCHAR2(10));
CREATE TABLE PRODUCT_LOG (LOG_DATE DATE, LOG_TEXT VARCHAR2(4000));
CREATE OR REPLACE PACKAGE PKG_PRODUCTS AS
TYPE t_filter IS TABLE OF VARCHAR2(250)
INDEX BY BINARY_INTEGER;
PROCEDURE SET_FILTER(p_vendor IN t_filter, p_item IN t_filter);
END PKG_PRODUCTS;
/
CREATE OR REPLACE PACKAGE BODY PKG_PRODUCTS AS
PROCEDURE SET_FILTER(p_vendor IN t_filter, p_item IN t_filter)
IS
v_text VARCHAR2(4000);
BEGIN
SELECT LISTAGG(Column_Value, ', ' ON OVERFLOW TRUNCATE '...' WITHOUT COUNT) WITHIN GROUP (ORDER BY 1) INTO v_text FROM TABLE(p_vendor);
INSERT INTO PRODUCT_LOG (LOG_DATE, LOG_TEXT) VALUES (SYSDATE, 'p_vendor:'||v_text);
SELECT LISTAGG(Column_Value, ', ' ON OVERFLOW TRUNCATE '...' WITHOUT COUNT) WITHIN GROUP (ORDER BY 1) INTO v_text FROM TABLE(p_item);
INSERT INTO PRODUCT_LOG (LOG_DATE, LOG_TEXT) VALUES (SYSDATE, 'p_item:'||v_text);
INSERT INTO PRODUCT_FILTER (PRODUCT_ID)
SELECT PRODUCT_ID FROM PRODUCTS
WHERE
(p_vendor(1) IS NULL
OR VENDOR IN (SELECT * FROM TABLE(p_vendor)))
AND
(p_item(1) IS NULL
OR ITEM IN (SELECT * FROM TABLE(p_item)));
END SET_FILTER;
END PKG_PRODUCTS;
/
-- To run
declare
P_VENDOR PKG_PRODUCTS.t_filter;
P_ITEM PKG_PRODUCTS.t_filter;
begin
P_VENDOR(1) := 'Vendor1';
P_ITEM(1) := 'Item1';
PKG_PRODUCTS.SET_FILTER(
P_VENDOR,
P_ITEM
);
end;
我在运行时收到此错误: 第 1 行错误 ORA-00902: 无效的数据类型 ORA-06512: 在“MARK.PKG_PRODUCTS”,第 13 行 ORA-06512: 在第 9 行
我正在使用 Oracle 19c
如有任何帮助,我们将不胜感激
我已将错误限制为“OR VENDOR IN (SELECT * FROM TABLE(p_vendor)))”,但无法找出确切的原因。
TYPE t_filter IS TABLE OF VARCHAR2(250) INDEX BY BINARY_INTEGER;
声明一个 PL/SQL 关联数组。它不能在 SQL 语句中使用 - 只能在 PL/SQL 语句中使用。
如果您想使用集合,请使用嵌套表类型(或
VARRAY
)并在 SQL 范围中定义它。
CREATE TYPE varchar2_250_list IS TABLE OF VARCHAR2(250);
然后:
CREATE OR REPLACE PACKAGE PKG_PRODUCTS AS
PROCEDURE SET_FILTER(
p_vendor IN varchar2_250_list,
p_item IN varchar2_250_list
);
END PKG_PRODUCTS;
/
CREATE OR REPLACE PACKAGE BODY PKG_PRODUCTS AS
PROCEDURE SET_FILTER(
p_vendor IN varchar2_250_list,
p_item IN varchar2_250_list
)
IS
v_text VARCHAR2(4000);
BEGIN
INSERT INTO PRODUCT_LOG (LOG_DATE, LOG_TEXT)
SELECT SYSDATE,
'p_vendor:'
|| LISTAGG(Column_Value, ', ' ON OVERFLOW TRUNCATE '...' WITHOUT COUNT) WITHIN GROUP (ORDER BY 1)
FROM TABLE(p_vendor);
INSERT INTO PRODUCT_LOG (LOG_DATE, LOG_TEXT)
SELECT SYSDATE,
'p_item:'
||LISTAGG(Column_Value, ', ' ON OVERFLOW TRUNCATE '...' WITHOUT COUNT) WITHIN GROUP (ORDER BY 1)
FROM TABLE(p_item);
INSERT INTO PRODUCT_FILTER (PRODUCT_ID)
SELECT PRODUCT_ID
FROM PRODUCTS
WHERE ( p_vendor IS EMPTY
OR VENDOR MEMBER OF p_vendor)
AND ( p_item IS EMPTY
OR ITEM MEMBER OF p_item);
END SET_FILTER;
END PKG_PRODUCTS;
/
注意:如果您决定使用
VARRAY
(而不是嵌套表类型),则 VARRAY
不支持 MEMBER OF
运算符。