ORA-21700: 对象不存在或被标记为删除关联数组作为从 ODP.NET 调用的输入参数

har*_*ang 4 .net oracle associative-array odp.net

我在 Oracle 12c 上有这个包代码

CREATE OR REPLACE PACKAGE Support_Data_Types AS
  TYPE ttDate            IS TABLE OF DATE  
END Support_Data_Types;

PROCEDURE GetData
(
    tabDates        IN SUPPORT_DATA_TYPES.TTDATE,
)

AS
BEGIN

    SELECT count(*) INTO n FROM table(tabDates);

END GetData;
Run Code Online (Sandbox Code Playgroud)

如果我从代码中调用它,PL/SQL它就可以工作

declare
    dates SUPPORT_DATA_TYPES.TTDATE;
begin
    dates(1) := To_DATE('12/31/2005','MM/DD/YYYY');
    dates(2) := To_DATE('03/31/2006','MM/DD/YYYY');
    dates(3) := To_DATE('06/30/2006','MM/DD/YYYY');
    dates(4) := To_DATE('09/30/2006','MM/DD/YYYY');

    MyPackage.GETVALUE(dates);
end;
Run Code Online (Sandbox Code Playgroud)

但是如果我从 ODP.NET 调用它,则会收到错误消息SELECT count(*) INTO n FROM table(tabDates);

ORA-21700: 对象不存在或已标记为删除

我的.NET 代码

    Public Function GetValue(dates As IEnumerable(Of Date))

        Using connection As IDbConnection = Odp.ConnectionBuilder.CreateDatabaseConnection()
            Using cmd As OracleCommand = New OracleCommand
                cmd.Connection = DirectCast(connection, OracleConnection)
                cmd.CommandType = CommandType.StoredProcedure
                cmd.CommandText = "MyPackage.GETVALUE"
                cmd.BindByName = True

                Using datesParam As OracleParameter = New OracleParameter()
                    datesParam.ParameterName = "tabDates"
                    datesParam.OracleDbType = OracleDbType.Date
                    datesParam.CollectionType = OracleCollectionType.PLSQLAssociativeArray
                    datesParam.Size = dates.Count()
                    datesParam.Direction = ParameterDirection.Input
                    datesParam.Value = dates.ToArray()
                    cmd.Parameters.Add(datesParam)
                End Using

                cmd.ExecuteNonQuery()

            End Using
        End Using
    End Function
Run Code Online (Sandbox Code Playgroud)

如果我与 Oracle 的示例代码进行比较,我不确定这里出了什么问题。

有人有一些见解吗?

shr*_*ice 6

经过几天的谷歌搜索,我这样更改了代码:

CREATE OR REPLACE PACKAGE Support_Data_Types AS
            TYPE ttDate            IS TABLE OF DATE
END Support_Data_Types;
PROCEDURE GetData
(
    tabDates IN SUPPORT_DATA_TYPES.TTDATE,
)
AS
    v_temp SUPPORT_DATA_TYPES.TTDATE:= tabDates;  -- assigned the parameter to a temporary variable
BEGIN
    SELECT count(*) INTO n FROM table(v_temp);
END GetData;
Run Code Online (Sandbox Code Playgroud)

我做的唯一一件事就是使用看起来相当多余的 v_temp 。但它有效。我做出了这个改变,因为我在这里搜索了这篇文章......它提到:

但请注意,从 12.1 开始,您无法直接在 TABLE 运算符内调用表函数。您必须在 PL/SQL 中调用它,将结果分配给变量,然后在 TABLE 中引用该变量。

尽管我的情况有所不同(我使用的是12.2),但它解决了我的问题。