如何使用ADO.net通过DB链接连接到远程数据库

时间:2013-08-27 06:32:09

标签: .net oracle

我想通过ODP.net(Oracle数据提供商)从远程Oracle数据库中搜索数据,但我总是收到以下错误消息:

    Oracle.DataAccess.Client.OracleException was unhandled
  Message=ORA-00936: missing expression
  Source=Oracle Data Provider for .NET
  ErrorCode=-2147467259
  DataSource=RETLMCC_ETLAPPL
  Number=936
  Procedure=""
  StackTrace:
       at Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure, Boolean bCheck)
       at Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, String procedure, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, Boolean bCheck)
       at Oracle.DataAccess.Client.OracleCommand.ExecuteReader(Boolean requery, Boolean fillRequest, CommandBehavior behavior)
       at Oracle.DataAccess.Client.OracleCommand.ExecuteReader()
       at WindowsFormsApplication1.Form1.Form1_Load(Object sender, EventArgs e) in C:\Documents and Settings\zhanzhex\my documents\visual studio 2010\Projects\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:line 52
       at System.Windows.Forms.Form.OnLoad(EventArgs e)
       at System.Windows.Forms.Form.OnCreateControl()
       at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
       at System.Windows.Forms.Control.CreateControl()
       at System.Windows.Forms.Control.WmShowWindow(Message& m)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
       at System.Windows.Forms.ContainerControl.WndProc(Message& m)
       at System.Windows.Forms.Form.WmShowWindow(Message& m)
       at System.Windows.Forms.Form.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.SafeNativeMethods.ShowWindow(HandleRef hWnd, Int32 nCmdShow)
       at System.Windows.Forms.Control.SetVisibleCore(Boolean value)
       at System.Windows.Forms.Form.SetVisibleCore(Boolean value)
       at System.Windows.Forms.Control.set_Visible(Boolean value)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at WindowsFormsApplication1.Program.Main() in c:\documents and settings\zhanzhex\my documents\visual studio 2010\Projects\WindowsFormsApplication1\WindowsFormsApplication1\Program.cs:line 18
       at System.AppDomain._nExecuteAssembly(Assembly 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)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

以下是我的代码:

        private void Form1_Load(object sender, EventArgs e)
    {
        //listBox1.Items.Add(new System.Windows.Forms.CheckBox());
        System.Windows.Forms.CheckBox chb1 = new System.Windows.Forms.CheckBox();
        chb1.Text = "test";
        checkedListBox1.Items.Add("test1");
        checkedListBox1.Items.Add("test2");
        checkedListBox1.Items.Add("test3");//RETLMCC_ETLAPPL
        string oradb = "Data Source=RETLMCC_ETLAPPL;User Id=ABC;Password=ABC;";
        OracleConnection conn = new OracleConnection();
        conn.ConnectionString = oradb;
        StringBuilder sb = new StringBuilder();
        sb.Append(" select table_name, column_name,data_type,data_length ");
        sb.Append(" from all_tab_columns@DB_LINK where table_name = @tableName order by column_name asc");
        string sqlStr = sb.ToString();
        //RETLMCC_ETLAPPL_SM_3_11
        OracleCommand cmd = new OracleCommand();

        cmd.CommandText = sqlStr;//"select name from ovsc_country_out";
        cmd.Connection = conn;
        cmd.CommandType = CommandType.Text;
        cmd.Connection.Open();

        OracleParameter paraTableName = new OracleParameter("@tableName", OracleDbType.Varchar2);
        paraTableName.Value = "COMPANYM1";

        OracleParameter paraDBLink = new OracleParameter("@DB_LINK", OracleDbType.Char);
        paraDBLink.Value = "@RETLMCC_ETLAPPL_SM_3_11";

        cmd.Parameters.Add(paraDBLink);
        cmd.Parameters.Add(paraTableName);

        OracleDataReader dr = cmd.ExecuteReader();
        while (dr.Read())
        {
            checkedListBox1.Items.Add(dr["column_name"].ToString());
        }
        if (conn.State == ConnectionState.Open)
        {
            conn.Close();
        }
    }

如果我搜索本地数据库但不搜索远程数据库,则代码运行良好,但是当我在SQL字符串中使用数据库链接时如何解决?

1 个答案:

答案 0 :(得分:0)

您不能将DB链接的名称作为参数传递,就像您不能将表的名称作为参数传递一样。

而不是:

sb.Append(" from all_tab_columns@DB_LINK where table_name = @tableName order by column_name asc");

OracleParameter paraDBLink = new OracleParameter("@DB_LINK", OracleDbType.Char);
paraDBLink.Value = "@RETLMCC_ETLAPPL_SM_3_11";

使用它:

sb.Append(" from all_tab_columns@RETLMCC_ETLAPPL_SM_3_11 where table_name = @tableName order by column_name asc");