【问题标题】:Error when trying to connect to Oracle 10g database from C# program employing minimal set-up configuration尝试从使用最少设置配置的 C# 程序连接到 Oracle 10g 数据库时出错
【发布时间】:2012-01-26 02:16:51
【问题描述】:

我在尝试从我正在开发的 C# 2008 Express Edition 应用程序连接到远程 Oracle 10g 数据库时遇到错误。我正在尝试使用一种极简、非侵入式的开发方法,以便将 ClickOnce 部署到用户工作站。

关于上述内容,我调查了以下文件(以及其他文件..)-

What is the minimal setup required to deploy a .NET application with Oracle client 11?

http://jeremybranham.wordpress.com/2011/04/25/oracle-instant-client-with-odp-net/

http://ora-00001.blogspot.com/2010/01/odpnet-minimal-non-intrusive-install.html

http://splinter.com.au/using-the-new-odpnet-to-access-oracle-from-c

Connect to Oracle with odp.net and the OCI from C#

鉴于我遇到的错误,我创建了一个简单的测试应用。由带有一个按钮的单个 (wpf) 页面组成。 在按钮的单击事件中,我尝试创建到 Oracle 数据库的连接 -

private void button1_Click( object sender, RoutedEventArgs e )
{
    OracleConnection oraConnect;

    // string previously used OK in other projects
    string connectionString = "Data Source=" +
           "(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = myServer)(PORT = 1521)))" +
           "(CONNECT_DATA =(SERVICE_NAME = myOracleDb)))" +
           ";Password=myPw;User ID=myID;";

    using ( oraConnect = new OracleConnection( connectionString ) )
    {
        try
        {
            if ( oraConnect.State == ConnectionState.Closed )
            {
                oraConnect.Open();
                MessageBox.Show( "oraConnect is attempting to open.." );
            }
            else
                MessageBox.Show( "oraConnect open to DB: " + oraConnect.ServerVersion.ToString() );
        }
        catch ( NullReferenceException nullExcept )
        {
            MessageBox.Show( "Caught error: ." + nullExcept.ToString() );
        }
        catch ( OracleException dbEx )
        {
            MessageBox.Show( "OraException - " + dbEx.Message.ToString());
        }
        catch ( Exception ex )
        {
            Exception current;
            current = ex;

            while ( current != null )
            {
                current = current.InnerException;
            }

            MessageBox.Show( "Db base exception - " + ex.GetBaseException().ToString() );
        }
        finally
        {
            oraConnect.Close();
        }
    }
}

根据上述文章中的信息,我确保以下 Dll 位于我的“bin”文件夹中 -

• oci.dll
• ociw32.dll
• orannzsbb10.dll
• oraocci10.dll
• oraociicus.dll
• msvcr71.dll

(最后一个绝望地命名...)并引用了“Oracle.DataAccess.dll”。

错误消息(在“catch (OracleException dbEx)”处)是 -

"Oracle.DataAccess.Client.OracleException was caught
  Message=""
  StackTrace:
       at Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure)
       at Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, Object src)
       at Oracle.DataAccess.Client.OracleConnection.Open()
       at OracleConnectionTest.Window1.button1_Click(Object sender, RoutedEventArgs e) in C:\Documents\Visual Studio 2008\Projects\OracleConnectionTest\OracleConnectionTest\Window1.xaml.cs:line 69
  InnerException: "

Line 69 is 'oraConnect.Open();'.

另外,报告如下——

"((Oracle.DataAccess.Client.OracleException)($exception)).DataSource' threw an exception of type 'System.NullReferenceException".

我从数据源中的 NullReferenceException 假设问题出在其中一个 dll 上(?),因为我在尝试引用之前“新建”了上面的 OracleConnection。

另外,代码执行跳转'catch(NullReferenceException nullExcept)' 并直接进入 OracleException 捕获。

抱歉,我说得有点意思,但希望这是有道理的吗? 任何帮助/建议表示赞赏!

【问题讨论】:

  • 你能ping通myServer吗?你试过通过 sqlplus 连接吗?
  • 你能 tnsping 'myOracleDb' 吗?
  • NullReferenceException 不是问题的原因。当您在 VisualStudio 中检查异常时会发生这种情况。这是一个调试工件,可以忽略。不幸的是,真正的异常似乎不包含任何错误消息。还是您在某个地方忽略了它?

标签: c# oracle clickonce oracleexception


【解决方案1】:

好的,很晚才回过神来,对此深表歉意!

在此期间,我们的数据库已升级(!)并更改 dll 列表以包含 -

  • oraocci11.dll
  • oraociccus11.dll
  • OraOps11w.dll
  • orannzsbb1.dll

从“10”版本开始,仍然没有成功,我使用以下内容编辑了 App.xaml(在此处和网络上进行了广泛搜索)-

    <system.data>
      <DbProviderFactories>
         <add name="OracleClient Data Provider"
              invariant="System.Data.OracleClient"
              description=".Net Framework Data Provider for Oracle"
              type="System.Data.OracleClient.OracleClientFactory, System.Data.OracleClient, Version=2.0.0.0, Culture=neutral, PublicKeyToken=##################"/>
      </DbProviderFactories>
   </system.data>

   <!-- publicKeyToken obtained using Reflector to investigate dll -->
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <dependentAssembly>
            <assemblyIdentity name="Oracle.DataAccess"
                              publicKeyToken="##################"
                              culture="neutral"/>
            <bindingRedirect oldVersion="10.2.0.100" 
                             newVersion="2.112.2.0"/>
         </dependentAssembly>
      </assemblyBinding>
   </runtime>

bindingRedirect 成功了!

dll 似乎非常依赖于兼容的版本号

希望我能说我真的了解如何它是如何工作的,但确实如此,而且我现在有工作连接......

【讨论】:

  • dll 似乎非常依赖兼容的版本号。如果不是非常敏感,Oracle 就什么都不是,而且我已经让整个服务器摆脱了 X.X.1/X.X.2 版本不匹配的问题。那将是我的调试建议,我很高兴这个问题得到解决。您应该接受自己的答案,以便其他人可以找到它。
【解决方案2】:

它发生在我身上。

经过一番伏都教之后,我从我的注册表中删除了这个密钥:HKEY_CURRENT_USER\Software\ORACLE,一切都恢复正常了。

【讨论】:

    【解决方案3】:

    确保正确设置 ODAC。我建议使用 TNSNAMES (你不应该在连接字符串 imo 中包含所有这些信息)。请参阅本文档 (11.2) 的 TNSNAMES setup 部分。另请参阅底部以了解常见的连接问题

    一旦完成,它应该就像将连接字符串放入项目的设置属性中一样简单:

    oraConnect = new OracleConnection(Properties.Settings.Default.MyConnString);
    

    在您的示例中,您的 oraConnect 尚未实例化(您只有“OracleConnection oraConnect”),因此失败的“新 OracleConnection”部分会导致空引用异常(如果我理解您对它在哪里中断的解释) )。 VS 中的调试器在这里也应该有所帮助;)

    编辑: 您可能想要设置一个简单的测试控制台应用程序,只需打开/关闭连接。除了正确设置 ODAC 之外,这可能会消除任何噪音。类似的东西(未经测试,假设 tnsnames 设置):

    使用 ...

    namespace Testbed {
      class Program {
        static void Main(string[] args) {
          try {
            string connStr="User Id=my_user;Password=my_pass;Data Source=my_sid;";
            OracleConnection oraConnect = new OracleConnection(connStr);
            oraConnect.Open();
            Console.WriteLine("Opened Connection");
            oraConnect.Close();
            Console.WriteLine("Complete");
            Console.ReadLine();
          catch (System.Exception e) {
            Console.WriteLine(e.Message);
            Console.ReadLine();
          } ...
    

    尝试运行它并报告从控制台返回的内容。

    【讨论】:

    • oraConnect 已被实例化。请参阅 using ( oraConnect = new OracleConnection... 中的 new 关键字。
    猜你喜欢
    • 2011-11-20
    • 2011-06-07
    • 1970-01-01
    • 1970-01-01
    • 2016-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多