我希望程序获取禁用权限列表,并在表中更新其记录。为了完成这个场景,我使用下面的代码将数组定义为数据库对象:
CREATE OR REPLACE TYPE T_DISABLE_LIST IS TABLE OF NUMBER(32)
然后我在过程签名中定义了一个输入参数,并得到了传递值。
PROCEDURE PRC_ROLE_PRIVILAGE_MANAGEMENT(P_REQ_USER_ID IN VARCHAR2,
P_DISABLE_LIST IN T_DISABLE_LIST,
P_RES_DESC OUT VARCHAR2)
BEGIN
UPDATE T_ PRIVILAGE p
SET P.ENABLE_STATUS = 0, P.GRANT_USERID = P_REQ_USER_ID
WHERE P.ID IN (SELECT * FROM TABLE(P_DISABLE_LIST));
COMMIT;
EXCEPTION
WHEN OTHERS THEN
RES_DESC := SUBSTR(SQLERRM,1, 400);
END;
此过程将成功编译。但是当我测试它时,我收到了这个错误:
ORA-22905:无法访问非嵌套表项的行
任何人都可以帮助我吗?并说明为什么这段代码无法正常工作?
最后,我该如何解决这个问题?
P.S:我的orcale版本是9.2 !!!
答案 0 :(得分:2)
这假设您使用的是Oracle 10g或更高版本(并且是在OP澄清他们使用的版本之前编写的)
使用MEMBER OF
运算符:
UPDATE T_PRIVILAGE
SET ENABLE_STATUS = 0,
GRANT_USERID = P_REQ_USER_ID
WHERE ID MEMBER OF P_DISABLE_LIST;
您还可以使用COLUMN_VALUE
伪列:
UPDATE T_PRIVILAGE
SET ENABLE_STATUS = 0,
GRANT_USERID = P_REQ_USER_ID
WHERE ID IN ( SELECT COLUMN_VALUE FROM TABLE( P_DISABLE_LIST ) );
为什么此代码无法正常工作?
SELECT * FROM TABLE( P_DISABLE_LIST )
从表中选择行。但是,该表由表集合表达式生成,并且没有底层数据库表来引用一行,因此Oracle生成ORA-22905
异常。(如果集合存储在嵌套表中,则会有一个基础表;这就是为什么在例外中特别提到这种情况的原因。
更新:PL / SQL解决方案:
FOR i IN 1 .. P_DISABLE_LIST.COUNT LOOP
UPDATE T_PRIVILAGE
SET ENABLE_STATUS = 0,
GRANT_USERID = P_REQ_USER_ID
WHERE ID = P_DISABLE_LIST(i);
END LOOP;