【问题标题】:AccessViolationException with provider OraOLEDB.Oracle on 12C?12C 上的提供程序 OraOLEDB.Oracle 的 AccessViolationException?
【发布时间】:2021-01-04 18:43:00
【问题描述】:

我们使用带有 MSDAORA 作为提供程序的 Oracle 11g,但由于 MSDAORA 将被弃用,我们必须为连接字符串转移到新的提供程序。我们现在也在使用 Oracle Client 12c

在我们使用之前:Provider=MSDAORA.1;Password=;User ID=;Data Source=****11G 。世界;持久安全信息=True

现在我们尝试使用:Provider=OraOLEDB.Oracle;OLEDB.NET=true;PLSQLRSet=true;密码=;用户 ID=*;数据源=****11G.world;Persist Security Info=True

问题是 IIS 崩溃,我们遇到了这个异常,我们已经尝试解决这个问题好几个星期了,但还没有成功:

异常详细信息
SystemAccessViolationException 试图读取或写入受保护的内存。这通常表明其他内存已损坏。

  • at System.Data.Common.UnsafeNativeMethods.1CommandTextExecute(IntPtr pUnkOuter, Guid& riid, tagDBPARAMS pDBParams, IntPtr& pcRowsAffected, 对象和 ppRowset)
  • System.Data.01eDb.0IeDbCommand.ExecuteCommandTextForSingleResult(tagDBPAFtAMS dbParams, Object& executeResult)
  • 在 System.Data.OleDb.OleDbCommand.ExecuteCommandText(Object& 执行结果)
  • 在 System.Data.OleDb.OleDbCommand.ExecuteCommand(CommandBehavior 行为,Object& executeResult)
  • 在 System.Data.01eDb.01eDbCommand.ExecuteReaderIntemal(CommandBehavior 行为,字符串方法)
  • 在 System.Data.OleDb.OleDbCommand.ExecuteReader(CommandBehavior 行为)
  • 在 System.Data.01eDb.0IeDbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior 行为)
  • 在 System.Data.Common.DbDataAdapter.Filllnternal(DataSet 数据集、DataTable0 数据表、Int32 startRecord、Int32 maxRecords、String srcTable、IDbCommand 命令、CommandBehavior 行为)
  • 在 System.Data.Common.DbDataAdapter.Fill(DataTableD 数据表,Int32 startRecord,Int32 maxRecords,IDbCommand 命令, CommandBehavior 行为)
  • 在 System.Data.Common.DbDataAdapter.Fill(DataTable 数据表)
  • 在 D: Projects\ M\Planned_Data.aspx.vb:line 637 中的 M.Planned_DataloadDataCurGrid()
  • 在 M.Planned_Data.cmbProgram_SelectedIndexChanged(对象发送者,EventArgs e)在 DAProjectAM \Planned_Data.aspx.vb:line 484
  • 在 System.Web.UI.WebControls.ListControl.OnSelectedIndexChanged(EventArgs e)
  • 在 System.Web.ULWebControls.DropDownListRaisePostDataChangedEvent()
  • 在 System.Web.UI.WebControls.DropDownListSystem.Web.ULIPostBackDataHandler.RaisePostDataChangedEvento
  • 在 System.Web.ULPage.RaiseChangedEvents()

这是一个简单的最小复制:

     Public Sub LoadGrid()
        Dim ocn As OleDbConnection = New OleDbConnection("Provider=OraOLEDB.Oracle;OLEDB.NET=true;PLSQLRSet=true; Password=*****;User ID=*****;Data Source=****11G.world;Persist Security Info=True")
        Dim oda As New OleDbDataAdapter
        Dim odataSet As New DataTable

        Dim opm As OleDbParameter

        Dim oCmd As New OleDbCommand

        opm = New OleDbParameter("pi_language_code", OleDbType.Char)
        opm.Value = "E"
        oCmd.Parameters.Add(opm)

        opm = New OleDbParameter("pi_year_id", OleDbType.Integer)
        opm.Value = "2020"
        oCmd.Parameters.Add(opm)

        opm = New OleDbParameter("pi_month_id", OleDbType.Integer)
        opm.Value = "2"
        oCmd.Parameters.Add(opm)

        opm = New OleDbParameter("pi_program_id", OleDbType.Integer)
        opm.Value = "4"
        oCmd.Parameters.Add(opm)

        opm = New OleDbParameter("pi_location_id", OleDbType.Integer)

        opm.Value = "2"

        oCmd.Parameters.Add(opm)

        Try

            ocn.Open()
            oCmd.Connection = ocn
            oCmd.CommandType = CommandType.StoredProcedure
            oCmd.CommandText = "***********"

            oCmd.ExecuteNonQuery()

            oda.SelectCommand = oCmd

            odataSet.Clear()
            oda.Fill(odataSet) 'This is where it crashes

          

            Dim rowcount As Integer = odataSet.Rows.Count

            dgCurrentYear.DataSource = odataSet
            dgCurrentYear.DataBind()

            If rowcount > 0 Then
                dgCurrentYear.Visible = True

            Else
                dgCurrentYear.Visible = False

            End If

        Catch ex As OleDbException
            ' Display the error


        Catch ex As Exception
            ' Display the error

        Finally
            ' Clean up
            If (Not ocn Is Nothing) AndAlso (Not ocn.State = ConnectionState.Closed) Then
                ocn.Close()
            End If

            ocn = Nothing
            opm = Nothing

        End Try

    End Sub

【问题讨论】:

  • opm = New OleDbParameter("pi_month_id", OleDbType.Integer) opm.Value = "2" 这样类型不匹配的代码让我怀疑Option Strict 没有被强制执行。如果未将 Option Strict On 设置为项目的默认设置,则将其设置为打开并纠正它提醒您的问题可能会导致代码速度提高三倍以上。
  • 另外,我怀疑ocn As OleDbConnection = New OleDbConnection("Provider=OraOLEDB.Oracle;OLEDB.NET=true;PLSQLRSet=true; Password=*****;User ID=*****;Data Source=****11G.world;Persist Security Info=True") Dim oda As New OleDbDataAdapter 应该在Try 内,或者可能是Using。像ocn = Nothing 这样的代码只是错误 - 代码应该调用ocn.Dispose()
  • @AndrewMorton 根据我的经验,Option Strict 检查DbType 以验证.Value。我希望它做到了。我总是开着它。
  • @Mary 说得好。

标签: vb.net oracle access-violation oraoledb


【解决方案1】:

所以我们通过删除oCmd.ExecuteNonQuery()这一行解决了这个问题

因为我不必调用 ExecuteNonquery,因为 DataAdapter 的填充方法正在处理这个问题。 Programming Practice: Using ExecuteNonQuery with SqlDataAdapter

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-18
    相关资源
    最近更新 更多