C# 执行包含oracle块的sql文件

C# 执行包含oracle块的sql文件,c#,sql,oracle,C#,Sql,Oracle,我需要帮助。我是Visual studio C的新手。 我正在创建一个WINDOWS窗体应用程序,它只有一个按钮和文本框。基本上我想做的是运行一个包含oracle块的sql文件,并希望从该块生成的输出(dbms_输出)显示在文本框中 到目前为止,我已经完成了调用sqlplus、执行文件以及通过消息框检索输出的任务。 但当我尝试对文本框执行同样的操作时,我得到了下面的运行时错误 System.InvalidOperationException未处理 Message=跨线程操作无效:控件“textB

我需要帮助。我是Visual studio C的新手。 我正在创建一个WINDOWS窗体应用程序,它只有一个按钮和文本框。基本上我想做的是运行一个包含oracle块的sql文件,并希望从该块生成的输出(dbms_输出)显示在文本框中

到目前为止,我已经完成了调用sqlplus、执行文件以及通过消息框检索输出的任务。 但当我尝试对文本框执行同样的操作时,我得到了下面的运行时错误

System.InvalidOperationException未处理 Message=跨线程操作无效:控件“textBox1”是从创建它的线程以外的线程访问的。 Source=System.Windows.Forms 堆栈跟踪: 在System.Windows.Forms.Control.get_Handle()中 位于System.Windows.Forms.Control.set\u WindowText(字符串值) 位于System.Windows.Forms.TextBoxBase.set_WindowText(字符串值) 在System.Windows.Forms.Control.set_文本中(字符串值) 位于System.Windows.Forms.TextBoxBase.set_Text(字符串值) 在System.Windows.Forms.TextBox.set_文本(字符串值)中 在WindowsFormsApplication1.Form1.myProcess\u OutputDataReceived(对象 发件人,DataReceivedEventArgs)在中 C:\Users\sj0087652.TECHMAHINDRA\AppData\Local\Temporary Projects\WindowsFormsApplication1\Form1.cs:第22行 at System.Diagnostics.Process.OutputReadNotifyUser(字符串数据) 位于System.Diagnostics.AsyncStreamReader.FlushMessageQueue()处 在System.Diagnostics.AsyncStreamReader.GetLinesFromStringBuilder()中 位于System.Diagnostics.AsyncStreamReader.ReadBuffer(IAsyncResult ar) 在System.Runtime.Remoting.Messaging.AsyncResult.SyncProcessMessage(IMessage 味精) 在System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(IMessage msg,IMessageSink replySink) 在System.Runtime.Remoting.Proxies.AgileAsyncWorkerItem.DoAsyncCall()中 在System.Runtime.Remoting.Proxies.AgileAsyncWorkerItem.ThreadPoolCallBack(对象 o) 在System.Threading.QueueUserWorkItemCallback.WaitCallback_上下文(对象 (州) 在System.Threading.ExecutionContext.Run(ExecutionContext ExecutionContext,ContextCallback回调,对象状态,布尔值 ignoreSyncCtx) 位于System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()处 在System.Threading.ThreadPoolWorkQueue.Dispatch()中 在System.Threading.\u ThreadPoolWaitCallback.PerformWaitCallback()中 内部异常:

现在我的问题如下:

  • 如何在文本框中获取输出
  • 有没有更好的方法来处理异常
  • 还有没有更好的方法通过C#执行包含oracle块的sql文件
  • 下面是我的代码:

    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; }
    }
    
    }
    )
    

    这可能是您的最佳选择:

    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线程上的函数(在本例中为委托)。您收到的错误是因为它试图跨线程编辑文本框


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

    问题在于,如果您使用的是.Net 4.5
    async
    /
    wait
    将解决您的问题,那么您正试图从另一个线程设置文本。否则,最好将类中的字符串设置为输出,并使用计时器轮询结果。或者您可以使用
    BeginInvoke
    在GUI线程上运行一些代码(这可能是您最好的选择):我使用的是visual express c#2010。这将帮助我,如果你编辑我的代码,并提供正确的代码,因为我是一个新的程序员。非常感谢你的回复…我已经修改了它以包含所有明显需要的内容。非常感谢。。。它是有效的:)。到我的文本框的输出是一个没有新行的字符。块完成PL/SQL过程已成功完成。块完成PL/SQL过程已成功完成。你能推荐一下吗。我希望输出如下。block complete(新行)PL/SQL过程已成功完成。(新行)block complete(新行)PL/SQL过程已成功完成。@user3870268打印时只需添加新行即可(我已编辑文章)。如果我帮了忙,请记下我的答案!我正在打印新行,但它没有打印在文本框中。。同时让我知道如何将您标记为应答者:)方框是否标记为多行?当您选择它时,在框的右上角应该有一个复选框,您可以勾选?是,它被选中。我也尝试过富文本框。但结果是一样的(