连接到Oracle 11g的VB.NET问题

时间:2012-10-19 15:42:11

标签: vb.net oracle11g vb.net-2010 odp.net

OS: Windows 7 64bit
VB: Visual Studio 2010
Oracle Client: 11g

我正在开发一个连接到Oracle 11g服务器的应用程序。我可以通过Oracle SQL Developer,ODBC(在SYSWOW64中)和VB Server Explorer中连接到Oracle服务器。

我正在使用位于以下位置的.NET参考Oracle.DataAccess:C:\ Oracle \ product \ 11.2.0 \ client_32 \ ODP.NET \ bin \ 2.x \ Oracle.DataAccess.dll

我已尝试将.DLL文件添加到我的bin文件夹中,如其他问题所示,但这不起作用。

有没有人有任何其他建议?

当我运行我的应用程序时,我得到以下内容: enter image description here

以下是详细信息:

System.TypeInitializationException was unhandled
  Message=The type initializer for 'Oracle.DataAccess.Client.OracleConnection' threw an exception.
  Source=Oracle.DataAccess
  TypeName=Oracle.DataAccess.Client.OracleConnection
  StackTrace:
       at Oracle.DataAccess.Client.OracleConnection..ctor(String connectionString)
       at Orc_Test_1.Form1.Button1_Click(Object sender, EventArgs e) in c:\Visual Studio 2010\Projects\Orc_Test_1\Orc_Test_1\Form1.vb:line 9
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
       at Orc_Test_1.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: Oracle.DataAccess.Client.OracleException
       DataSource=""
       ErrorCode=-2147467259
       Message=The provider is not compatible with the version of Oracle client
       Number=-11
       Procedure=""
       Source=Oracle Data Provider for .NET
       StackTrace:
            at Oracle.DataAccess.Client.OracleInit.Initialize()
            at Oracle.DataAccess.Client.OracleConnection..cctor()
       InnerException: 

VB.NET代码:

Imports System.Data
Imports Oracle.DataAccess.Client ' ODP.NET Oracle managed provider
Imports Oracle.DataAccess.Types

Public Class Form1

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        Dim oradb As String = "Data Source=SERVER1;Persist Security Info=True;User ID=username;Password=password;Unicode=True" 'From Server Explorer
        'Dim oradb As String = "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=Server1.host.net)(PORT=1522))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=Server1))); USER ID = username;Password = password;" 'From TNSnames.ora
        Dim conn As New OracleConnection(oradb)  '<--- Error happens on this line
        conn.Open()
        Dim cmd As New OracleCommand
        cmd.Connection = conn
        cmd.CommandText = "select system_id from schema1.system_impacted where system_name = AWESOME"
        cmd.CommandType = CommandType.Text
        Dim dr As OracleDataReader = cmd.ExecuteReader()
        dr.Read()
        Label1.Text = dr.Item("system_id")
        conn.Dispose()
    End Sub
End Class

5 个答案:

答案 0 :(得分:3)

我感觉到你的痛苦,只是在部署情况下经历了类似的事情。您可能安装了多个客户端,并且您的环境正在为旧版本提供dll(即使您的项目中正确引用了最新的oracle.dataaccess.dll)。在您的开发环境中修复此问题是一回事,prod部署服务器是另一回事。不确定你的部署情况,但这对我有用。

在尝试升级现有oracle home中的odp.net,添加新的oracle home之后,我发现解决所有问题的最简单方法是从Oracle下载最新的odac with xcopy deployment,并按照自述文件进行操作(另请参阅here以获取较旧的文章)。基本上你将运行一个install.bat文件在本地设置(在单独的文件夹中,我的是c:\ oracle_odac),然后将你的项目引用更改为指向这个新文件夹中的oracle.dataaccess.dll(我使用了4而不是2.x),并将新文件夹的bin dirs添加到路径的前面(c:\ oracle_odac \ bin和c:\ oracle_odac \ odp.net \ bin \ 4)。在部署服务器上,您只需复制整个c:\ oracle_odac文件夹(通过xcopy或者),然后设置路径。

那就是说,我焦急地等待来自Oracle的fully managed odp.net的生产版本(现在测试版)。

编辑:只是补充一点,如果你在app或web配置文件中设置dllpath,你可以避免搞乱PATH。例如:

<configuration>
...
    <configSections>
      <section name="oracle.dataaccess.client" type="System.Data.Common.DbProviderConfigurationHandler, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>  
...

<oracle.dataaccess.client>
    <settings>
      <add name="DllPath" value="c:\oracle_odac\bin"/>
    </settings>
  </oracle.dataaccess.client>
...

这将覆盖其他设置,例如registry或machine.config。它将允许多个odp.net配置安静地存在,并允许每个应用程序指向它在同一服务器上所需的版本。

答案 1 :(得分:1)

通常在您构建x64应用程序时会发生这种情况,该应用程序试图获取不起作用的x32驱动程序。

在这种情况下你做了什么(而且非常痛苦):

  • 将x32 oracle客户端安装到oraclehome1
  • 将x64 oracle客户端安装到oraclehome2

确保您的应用程序构建(x64,x32)指向正确的oraclehome。我没有那个代码方便,但我相信它是连接字符串中的“Home = oraclehome2”或者类似的东西。

答案 2 :(得分:1)

我删除了“控制面板”的“程序”部分中提供的所有oracle客户端。然后我进入注册表搜索“Oracle”并删除了Oracle客户端的所有实例/引用。注册表删除和重新启动3小时后,我安装了11g客户端,一切都按预期工作。

注意:在搜索注册表中搜索“Oracle”时,可能会引用VB版本的Oracle,或者引用“Oracle”的Crytsal Reports驱动程序。我没有删除这些。因此,请注意您要删除的注册表项的文件位置和/或语法。

/读。它有效。

答案 3 :(得分:0)

下载ODAC 32 / ODAC 64位,具体取决于OS,VS和oracle 11g的兼容性。 使用oracle 11g 32,os 32位,oracle 32位或oracle 64位,os 64位和oracle 11g 64位。

答案 4 :(得分:0)

根据我的经验,在尝试了tbone的建议,玩PATH env变量和其他不成功的播放后,立即起作用的解决方案是保存下面列出的8个DLL文件的副本。 vb.net可执行文件,然后在同一文件夹中添加对Oracle.DataAccess.dll的引用。

C:\Users\Legarcia\Documents\Visual Studio 2010\Projects\LabRetention\LabRetention\bin\Debug>dir *.dll
 Volume in drive C is OS
 Volume Serial Number is 10EC-8C5D

 Directory of C:\Users\Legarcia\Documents\Visual Studio 2010\Projects\LabRetention\LabRetention\bin\Debug

09/30/2008  07:57 PM           348,160 msvcr71.dll
10/01/2008  02:22 AM           520,192 oci.dll
10/01/2008  01:56 AM           352,256 ociw32.dll
08/12/2009  07:13 AM         1,011,712 Oracle.DataAccess.dll
09/18/2008  08:47 PM         1,130,496 orannzsbb11.dll
10/01/2008  01:48 AM           868,352 oraocci11.dll
10/01/2008  02:45 AM       117,604,352 oraociei11.dll
08/12/2009  07:21 AM           413,696 OraOps11w.dll
               8 File(s)    122,249,216 bytes
               0 Dir(s)  238,127,943,680 bytes free

在开发/测试/ debuging时,DLL的集合被复制到.. \ projects \ {Your project} \ bin \ Debug

例如:[C:\ Users \ Legarcia \ Documents \ Visual Studio 2010 \ Projects \ LabRetention \ LabRetention \ bin \ Debug]

当为用户发布应用程序时,只需将DLL复制到EXE的同一目录

这似乎隔离了所有其他Ora客户端安装。

VB.net应用程序中使用的连接字符串是根据其他客户端目录中的TNSNAMES.ORA文件中的信息创建的。

问候。

LE +