【发布时间】: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