【问题标题】:ORA-21700: object does not exist or is marked for delete for Associative Array as input parameter called from ODP.NETORA-21700: 对象不存在或被标记为关联数组的删除作为从 ODP.NET 调用的输入参数
【发布时间】:2019-07-01 23:23:38
【问题描述】:

我在 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;

如果我从 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;

但如果我从 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

如果我与 Oracle 的 sample code 进行比较,我不确定这里有什么问题。

有人有见解吗?

【问题讨论】:

  • 我可能知道您的问题是什么...删除此datesParam.Size = dates.Count() 并设置datesParam.ArrayBindSize。此外,通过不同的执行,您执行两次 - 这里:dates.Count() 和这里:dates.ToArray()。让这个函数接受date() 并调用它GetValue(enumerableDate.ToArray())。看我类似的回答,只有参数是OUT stackoverflow.com/a/31387136/1704458
  • 而且你不需要在参数上使用using。看看里面 - 它几乎什么都不做。
  • 我也有类似的问题。但是,相同的代码代码可以在另一台 Oracle 服务器上运行。我不知道是什么导致了这种差异。

标签: .net oracle associative-array odp.net


【解决方案1】:

经过几天的谷歌搜索,我以这种方式更改了代码:

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;

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

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

虽然我的情况不同(我使用的是 12.2),但它解决了我的问题。

【讨论】:

  • 我知道我的回答看起来很奇怪,而且我自己一开始也不相信。这只是 12.2 错误的解决方法。如果您对此投反对票,请告诉我原因。谢谢!
  • 天啊,我也花了几天时间在谷歌上搜索同样的问题。你让我免于发疯!谢谢!
猜你喜欢
  • 1970-01-01
  • 2016-03-20
  • 2017-04-13
  • 2016-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-25
相关资源
最近更新 更多