0
Framework Version: v4.0.30319 
Description: The process was terminated due to an unhandled exception.
Exception Info: System.AccessViolationException
Stack:
  at Oracle.DataAccess.Client.OracleParameter.SetStatus(Int32)
  at Oracle.DataAccess.Client.OracleParameter.PreBind(Oracle.DataAccess.Client.OracleConnection, IntPtr, Int32, Boolean)
  at Oracle.DataAccess.Client.OracleCommand.ExecuteNonQuery()

我的应用程序因此异常而崩溃。上下文是:我们正在尝试执行一个接受两个参数的存储过程,我们正在对命令文本中的参数使用名称绑定。

例子:

OraCommand.CommandText = "begin LOAD_UTILS.TRUNCATE_TABLE(:a1,:a2); end;"
OraCommand.Parameters.Add(New OracleParameter("a1", OracleDbType.Varchar2, 1000))
OraCommand.Parameters(0).Direction = ParameterDirection.Input
OraCommand.Parameters(0).Value = params(2)
OraCommand.Parameters.Add(New OracleParameter("a2", OracleDbType.Varchar2, 1000))
OraCommand.Parameters(1).Direction = ParameterDirection.Input
OraCommand.Parameters(1).Value = params(3)

我观察到的奇怪之处是,我们在 for 循环中运行这些语句以进行一定次数的重试,以防万一出现任何错误,OraCommand 是一个实例变量,因此参数集合不会被清除。

在第 1 次迭代中:添加参数 a1、a2
在第 2 次迭代中:前两个参数已经存在,我们再次添加名称为 a1 和 a2 的参数。...

没有看到问题,当我在每次迭代开始时清除参数集合时,但我无法提出导致问题的理论,有什么想法吗?

4

2 回答 2

1

您正在使用 ODP.Net,它的工作方式是,.Net C# API 只是在 C 中公开它们的服务层的包装器,它与 OCI(Oracle 调用接口)通信,主要是访问冲突异常来自它们的服务层或 OCI ,因为在托管代码 (.Net C#) 中存在访问冲突 (AV) 并不可行,因此 CLR 不允许这样做。调试问题的更简单方法是使用 Windbg,加载符号,它会为您指出导致问题的确切方法,这将是非托管代码,但挑战是您将拥有最多公开的发布版本符号,这没有多大帮助,其他选择是将代码问题发布到 Oracle Technet,ODP.Net 开发人员可以在其中提供解决方法和修复。但是在此之前,我认为您的代码存在某些问题:

在循环中,以下行将每次添加一个新参数 a1 和 a2

OraCommand.Parameters.Add(New OracleParameter("a1", OracleDbType.Varchar2, 1000))
OraCommand.Parameters.Add(New OracleParameter("a2", OracleDbType.Varchar2, 1000))

您在预期中遇到的行为,因为只有在创建新参数之后,您才在索引 0 和 1 处设置值和方向,每次都相同,在每次迭代中,您最终都会向 OracleCommand 对象添加两个新参数并且在某个地方弄乱了内部结构,因为您所做的是不正确的。正确的方法是在循环中遵循代码:

OracleParameter A1 = OracleParameter("a1", OracleDbType.Varchar2, 1000)
A1.Direction = ParameterDirection.Input
A1.Value = params[2]
OracleCommand.Parameters[0] = A1;

OracleParameter A2 = OracleParameter("a2", OracleDbType.Varchar2, 1000)
A1.Direction = ParameterDirection.Input
A1.Value = params[3]
OracleCommand.Parameters[1] = A2;

实际上,您的代码中的另一个奇怪的事情是使用以下代码访问数组之类的集合:

OraCommand.Parameters(0).Value = params(2)

这在 C# 中是不可能的,你必须使用方括号 [],在我看来你必须使用 VB.Net,因为即使你new不正确,它也不New在 C#

于 2014-12-17T05:32:15.000 回答
0

@Mrinal Kamboj 你是对的,代码在 VB.NET 中;尝试执行 ExecuteNonQuery 时引发异常。我尝试了 WinDbg,这就是它所提供的: 在此处输入图像描述

于 2014-12-17T15:28:05.107 回答