从12.1更新到Oracle 12.2后,表操作符出错(ORA-21700)

Aar*_*nds 7 sql oracle plsql oracle12c oracle-manageddataaccess

我们的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;
Run Code Online (Sandbox Code Playgroud)

这是一个失败的过程:

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;
Run Code Online (Sandbox Code Playgroud)

如果select * from table(STATUSID_ARR)部分被移除,它将运行.

在12.2中对关联数组使用表运算符是否存在问题?问题可能源于其他问题吗?

XIN*_*ING 1

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

是的,这是真的。在 之前,您不能在块内的语句Oracle 12c范围内使用关联数组。但是,Oracle 确保在推出新版本时,旧版本不会受到影响。我尝试测试你的代码,它在我这边工作正常。看起来问题出在其他地方,可能是使用 C# 时出现的问题。参见下面的演示:SQLPLSQL

我的Oracle版本:

SQL> select * from v$version;

BANNER
------     
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
Run Code Online (Sandbox Code Playgroud)

表数据:

SQL>SELECT * from TEST;
  col
  ---
   1
   2
   3
Run Code Online (Sandbox Code Playgroud)

包裹:

--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;
Run Code Online (Sandbox Code Playgroud)

呼叫:

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;
Run Code Online (Sandbox Code Playgroud)

输出:

Return From Procdure--1
Return From Procdure--2
Run Code Online (Sandbox Code Playgroud)