执行包含oracle块的sql文件

时间:2014-07-23 19:53:40

标签: c# sql oracle

需要帮助。我是Visual Studio C#的新手。 我只用一个按钮和文本框创建一个WINDOWS FORM APPLICATION。基本上我想要做的是运行一个包含oracle块的sql文件,并希望从块生成的输出(dbms_output)显示在文本框中。

直到现在我完成了调用sqlplus并执行该文件并通过消息框检索输出。 但是当我尝试使用文本框执行相同操作时,我会遇到运行时错误。

  

System.InvalidOperationException未处理         Message =跨线程操作无效:控制'textBox1'从其创建的线程以外的线程访问。         来源= System.Windows.Forms的         堆栈跟踪:              在System.Windows.Forms.Control.get_Handle()              在System.Windows.Forms.Control.set_WindowText(String value)              at System.Windows.Forms.TextBoxBase.set_WindowText(String value)              在System.Windows.Forms.Control.set_Text(String value)              at System.Windows.Forms.TextBoxBase.set_Text(String value)              at System.Windows.Forms.TextBox.set_Text(String value)              在WindowsFormsApplication1.Form1.myProcess_OutputDataReceived(对象   sender,DataReceivedEventArgs e)in   C:\ Users \用户sj0087652.TECHMAHINDRA \应用程序数据\本地\临时   Projects \ WindowsFormsApplication1 \ Form1.cs:第22行              at System.Diagnostics.Process.OutputReadNotifyUser(String data)              在System.Diagnostics.AsyncStreamReader.FlushMessageQueue()              在System.Diagnostics.AsyncStreamReader.GetLinesFromStringBuilder()              在System.Diagnostics.AsyncStreamReader.ReadBuffer(IAsyncResult ar)              在System.Runtime.Remoting.Messaging.AsyncResult.SyncProcessMessage(IMessage)   MSG)              在System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(IMessage)   msg,IMessageSink replySink)              在System.Runtime.Remoting.Proxies.AgileAsyncWorkerItem.DoAsyncCall()              在System.Runtime.Remoting.Proxies.AgileAsyncWorkerItem.ThreadPoolCallBack(Object   O)              在System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object   州)              at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean   ignoreSyncCtx)              在System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()              在System.Threading.ThreadPoolWorkQueue.Dispatch()              在System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()         的InnerException:

现在我的问题如下:

  1. 如何在文本框中输出输出。
  2. 有没有更好的处理例外的方法。
  3. 有没有更好的方法通过C#执行包含oracle块的sql文件。
  4. 以下是我的代码:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication1
    {
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
    
        void myProcess_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
        {
            MessageBox.Show(e.Data);
            textBox1.Text += e.Data;
        }
    
        void myProcess_Exited(object sender, EventArgs e)
        {
            MessageBox.Show("Exit");
    
        }
    
        void myProcess_ErrorDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
        {
            MessageBox.Show("error", e.Data);
        } 
        private void button1_Click(object sender, EventArgs e)
        {
            myProcess = new System.Diagnostics.Process();
            myProcess.StartInfo.FileName = "sqlplus.exe";
            myProcess.StartInfo.WorkingDirectory = "";
            myProcess.StartInfo.Arguments = "-s hr/hr@XE";
            myProcess.StartInfo.RedirectStandardInput = true;
            myProcess.StartInfo.RedirectStandardOutput = true;
            myProcess.StartInfo.RedirectStandardError = true;
            myProcess.StartInfo.UseShellExecute = false;
            myProcess.StartInfo.CreateNoWindow = true;
            myProcess.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(myProcess_OutputDataReceived);
            myProcess.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(myProcess_ErrorDataReceived);
            myProcess.Exited += new EventHandler(myProcess_Exited);
            myProcess.Start();
            myProcess.BeginErrorReadLine();
            myProcess.BeginOutputReadLine();
            myProcess.StandardInput.WriteLine("@C:\\Users\\sj0087652\\Documents\\trial_script.sql");
    
            myProcess.Close(); 
        }
               public System.Diagnostics.Process myProcess { get; set; }
    }
    
    }
    )
    

1 个答案:

答案 0 :(得分:0)

这可能是您最好的选择:

delegate void AddContentDelegate(string Text);
public partial class Form1 : Form
{
    AddContentDelegate AddContent;
    public Form1()
    {
        InitializeComponent();

        AddContent = new AddContentDelegate(AddContentFunction);
    }

    void AddContentFunction(string Text)
    {
        MessageBox.Show(Text);
        textBox1.Text += Text + "\r\n";
    }


    void myProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        BeginInvoke(AddContent, e.Data);
    }

    void myProcess_Exited(object sender, EventArgs e)
    {
        MessageBox.Show("Exit");

    }

    void myProcess_ErrorDataReceived(object sender, DataReceivedEventArgs e)
    {
        MessageBox.Show("error", e.Data);
    } 
    private void button1_Click(object sender, EventArgs e)
    {
        myProcess = new System.Diagnostics.Process();
        myProcess.StartInfo.FileName = "sqlplus.exe";
        myProcess.StartInfo.WorkingDirectory = "";
        myProcess.StartInfo.Arguments = "-s hr/hr@XE";
        myProcess.StartInfo.RedirectStandardInput = true;
        myProcess.StartInfo.RedirectStandardOutput = true;
        myProcess.StartInfo.RedirectStandardError = true;
        myProcess.StartInfo.UseShellExecute = false;
        myProcess.StartInfo.CreateNoWindow = true;
        myProcess.OutputDataReceived += new DataReceivedEventHandler(myProcess_OutputDataReceived);
        myProcess.ErrorDataReceived += new DataReceivedEventHandler(myProcess_ErrorDataReceived);
        myProcess.Exited += new EventHandler(myProcess_Exited);
        myProcess.Start();
        myProcess.BeginErrorReadLine();
        myProcess.BeginOutputReadLine();
        myProcess.StandardInput.WriteLine("@C:\\Users\\sj0087652\\Documents\\trial_script.sql");

        myProcess.Close(); 
    }
    public System.Diagnostics.Process myProcess;
}

BeginInvoke将在GUI线程上调用该函数(或本例中的Delegate)。您得到的错误是因为它试图跨线程编辑文本框。

您可能希望将其更改为Invoke,以防止使用弹出框发送垃圾邮件。唯一的区别是Invoke将等到函数完成后再继续。