我们的Oracle数据库最近已从12.1.0.2更新为12.2.0.1 +补丁集更新20180417.
自更新以来,我们在调用plsql过程时遇到以下错误: ORA-21700:对象不存在或标记为删除
我们已经缩小了问题,这似乎是由在包中定义的关联数组上使用表运算符引起的。我的所有研究表明,我们正在做的是在12.1中引入的,并且仍应在12.2中工作。
以下是与相关类型定义失败的过程的简化版本。它是使用托管数据访问从c#代码调用的。
这是包中的关联数组类型定义:
TYPE NUMBER_ARRAY IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
这是一个失败的程序:
PROCEDURE GetReadingStatus(
STATUSID_ARR IN NUMBER_ARRAY,
P_RETURNS OUT SYS_REFCURSOR
)
BEGIN
OPEN P_RETURNS FOR
SELECT * FROM READINGSTATUS rs
WHERE rs.statusID IN (select * from table(STATUSID_ARR));
END;
如果移除select * from table(STATUSID_ARR)
部分,则会运行。
在12.2中对关联数组使用表运算符是否存在问题?问题可能源于其他问题吗?
答案 0 :(得分:1)
我的所有研究表明,我们正在做的事情是在12.1中介绍的 并且仍应在12.2中工作。
是这是真的。在Oracle 12c
之前,您不能在SQL
块中的PLSQL
语句范围内使用关联数组。但是,Oracle确保在引入新版本时,旧版本不会受到影响。我试着测试你的代码,并且我的工作正常。看起来问题在其他地方,使用C#时可能会出现问题。见下面的演示:
我的Oracle版本:
SQL> select * from v$version;
BANNER
------
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
表格数据:
SQL>SELECT * from TEST;
col
---
1
2
3
<强> 包装: 强>
--Package Specification
CREATE OR REPLACE PACKAGE TESTTT
AS
TYPE NUMBER_ARRAY IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
Procedure GetReadingStatus (
STATUSID_ARR IN NUMBER_ARRAY,
P_RETURNS OUT SYS_REFCURSOR
);
END;
/
--Package Body
CREATE OR REPLACE PACKAGE BODY TESTTT
AS
PROCEDURE GetReadingStatus(
STATUSID_ARR IN NUMBER_ARRAY,
P_RETURNS OUT SYS_REFCURSOR
)
Is
BEGIN
OPEN P_RETURNS FOR
SELECT *
FROM TEST
where col IN (SELECT * FROM TABLE(STATUSID_ARR));
END;
END TESTTT;
<强> 调用: 强>
DECLARE
var TESTTT.NUMBER_ARRAY;
v_out sys_refcursor;
num NUMBER;
BEGIN
var(1):= '1';
var(2):= '2';
TESTTT.GetReadingStatus(STATUSID_ARR=>var,
P_RETURNS =>v_out);
Loop
fetch v_out INTO num;
exit WHEN v_out%notfound;
dbms_output.put_line('Return From Procdure--'||num);
end loop;
end;
<强> 输出: 强>
Return From Procdure--1
Return From Procdure--2
答案 1 :(得分:1)
从Oracle 12c升级到19c后,我遇到了相同或类似的问题。我不确定为什么Oracle升级会引起问题,而且我也不太了解我的修复程序为什么起作用!
在我的存储过程中,将Oracle的TABLE函数应用于某些存储过程输入时,出现错误:“ ORA-21700:对象不存在或被标记为删除”。
但是,在将Oracle的TABLE函数应用于存储过程中的局部变量的地方,没有错误。因此,我的解决方法只是在使用TABLE函数之前将存储过程输入分配给局部变量,从而以某种方式解决了该问题!
CREATE OR REPLACE PACKAGE my_types IS
TYPE integers IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
TYPE reals IS TABLE OF FLOAT INDEX BY BINARY_INTEGER;
END my_types;
/
CREATE OR REPLACE PROCEDURE order_list
(
i_order_numbers IN my_types.integers,
o_order_numbers OUT my_types.integers,
o_order_values OUT my_types.reals
)
IS
r_order_numbers my_types.integers;
CURSOR order_list_cur (p_order_numbers my_types.integers)
IS
SELECT order_number, order_value
FROM orders
WHERE order_number IN (SELECT * FROM TABLE(p_order_numbers))
;
order_list_rec order_list_cur%ROWTYPE;
rec_no BINARY_INTEGER;
BEGIN
r_order_numbers := i_order_numbers;
rec_no := 0;
OPEN order_list_cur(r_order_numbers);
LOOP
FETCH order_list_cur INTO order_list_rec;
EXIT WHEN order_list_cur%NOTFOUND;
rec_no := rec_no + 1;
o_order_numbers(rec_no) := order_list_rec.order_number;
o_order_values(rec_no) := order_list_rec.order_value;
END LOOP;
CLOSE order_list_cur;
END order_list;
答案 2 :(得分:0)
这个问题很像我的情况,当我在12.2中遇到相同的错误,但没有12.1时出现相同的错误。我已经发布了答案here,因为该答案是使用包而不是模式定义的类型。也许这个问题可以用同样的方法解决。只需尝试添加相同类型的temp变量并为其分配参数即可。