OleDB正在将.NET 2.0更改为4.6.1并返回记录集

OleDB正在将.NET 2.0更改为4.6.1并返回记录集,.net,database,stored-procedures,oledb,oledbdatareader,.net,Database,Stored Procedures,Oledb,Oledbdatareader,我正在将一个旧的VB项目(在C#之前)从.NET2升级到4.6.1 需要注意的是,当涉及到数据库提供者时,这个项目是不可知的。它仅通过更改连接字符串来使用SQL Server或Oracle。据推测,它将针对任何其他OleDB数据源工作。因此,必须避免直接引用Oracle二进制文件。例如,下面使用的是Oracle,但我无法引用源代码中的Oracle.any 这是我的问题: 这段代码在.NET 2.0下完美执行: cmdDB.Transaction = transDB cmdDB.C

我正在将一个旧的VB项目(在C#之前)从.NET2升级到4.6.1

需要注意的是,当涉及到数据库提供者时,这个项目是不可知的。它仅通过更改连接字符串来使用SQL Server或Oracle。据推测,它将针对任何其他OleDB数据源工作。因此,必须避免直接引用Oracle二进制文件。例如,下面使用的是Oracle,但我无法引用源代码中的Oracle.any

这是我的问题:

这段代码在.NET 2.0下完美执行:

    cmdDB.Transaction = transDB
    cmdDB.CommandText = "myPackage.MyFunction"
    cmdDB.CommandType = CommandType.StoredProcedure
    cmdDB.Parameters.Add("p_extract_key", someValue)
    cmdDB.Connection = conDB
    Try
        rdrDB = cmdDB.ExecuteReader(CommandBehavior.SingleRow)
    Catch ex As Exception
        Debug.WriteLine(ex.ToString)
        Throw ex
    End Try

    ```
    Then it uses rdrDB to read the row
将“Parameters.Add”更改为“Parameters.AddValue”后,它将根据4.6.1进行编译

但是,由于“PLS-00306:调用'MyFunction'时参数的数量或类型错误”,因此失败

存储过程的签名如下所示:

 TYPE outcur_type is REF CURSOR;
 procedure OBJEX_PR_OFFICE(p_extract_key in varchar2, outcur out outcur_type);
“outcur”属于REF\U CURSOR类型

猜测有一个突破性的更改现在需要我为游标提供OUT参数,我在尝试之前添加了以下代码行:

    Dim outCursor As New OleDbParameter
    outCursor.ParameterName = "outcur"
    outCursor.Direction = ParameterDirection.Output
    cmdDB.Parameters.Add(outCursor)
现在我们知道了:

Exception thrown: 'System.InvalidOperationException' in System.Data.dll
System.InvalidOperationException: String[1]: the Size property has an invalid size of 0.
   at System.Data.OleDb.OleDbParameter.BindParameter(Int32 index, Bindings bindings)
   at System.Data.OleDb.OleDbCommand.CreateAccessor()
   at System.Data.OleDb.OleDbCommand.InitializeCommand(CommandBehavior behavior, Boolean throwifnotsupported)
   at System.Data.OleDb.OleDbCommand.ExecuteCommand(CommandBehavior behavior, Object& executeResult)
   at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method)
   at System.Data.OleDb.OleDbCommand.ExecuteReader(CommandBehavior behavior)
我花了几个小时尝试各种参数值的组合。在我看来,将outCursor参数的DbType设置为DbType.Cursor或OleDBType.Cursor可能会有所帮助,但似乎不存在类似的类型


我可以修改应用程序来定义一个接口,为不同的数据库提供者创建实现,并避免OleDB。但在我告诉我的客户他们项目的成本即将爆炸之前,我想我应该征求社区的意见


关于下一步该怎么做,有什么想法吗?

“我可以修改应用程序来定义一个接口,为不同的数据库提供程序创建实现,并避免OleDB”-不幸的是,这是不可避免的,除非您的程序只使用最琐碎的查询。不同的RDBMS都有自己独特且不兼容的SQL方言,这意味着使用OLE-DB试图与多个DB引擎兼容只是一个遥远的梦想。这也是为什么每个人都喜欢实体框架(因为Linq抽象了SQL,前提是表模式兼容)。我看到您将查询存储在存储过程中——在这种情况下,您可能不需要使用OLE-DB。对于这段特定的代码,您需要为输出参数添加一个参数。看起来在.NETFramework2.0中,您不需要为
out
cursor参数提供显式参数,但现在需要了。如果您只是忽略了该参数,您可以使用
Variant
作为类型吗?@Dai您是正确的,非常简单的查询。然而,如果你仔细考虑事情,并与ANSI保持密切联系,你会惊奇地发现非琐碎的事情竟然可以完成。避免由专有特性创建的陷阱会给许可证持有者带来一些自由滥用。无论如何,这个项目是在2003年设计的。在微软基本上使.NET1.1变得无用之后,它在2004-2005年被重写。从那时起,它已经针对Oracle和SQL Server处理了数十亿个事务,这些事务都是相同的二进制文件。由于这个问题,我不想重写它。看看这是否提供了任何线索: