8

我们的 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 中对关联数组使用表运算符有问题吗?问题可能源于其他原因吗?

4

3 回答 3

2

从 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;
于 2020-08-19T09:51:55.463 回答
1

我所有的研究表明,我们正在做的事情是在 12.1 中引入的,并且应该在 12.2 中仍然有效。

的,这是真的。在 之前Oracle 12c,您不能在块内的SQL语句范围内使用关联数组PLSQL。但是,Oracle 确保在引入新版本时,旧版本不会受到影响。我试图测试你的代码,并在我的最后工作正常。看起来问题在其他地方,在使用 C# 时可能是一些问题。请看下面的演示:

我的甲骨文版本:

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
于 2018-06-14T05:12:33.057 回答
0

这个问题很像我在 12.2 但不是 12.1 时遇到相同错误时的情况。我在这里发布了我的答案,因为它使用的是包而不是模式定义的类型。也许这个问题可以用同样的方式解决。只需尝试添加相同类型的临时变量并将参数分配给它。

于 2019-06-20T01:35:03.953 回答