C# 执行包含oracle块的sql文件
我需要帮助。我是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文件,c#,sql,oracle,C#,Sql,Oracle,我需要帮助。我是Visual studio C的新手。 我正在创建一个WINDOWS窗体应用程序,它只有一个按钮和文本框。基本上我想做的是运行一个包含oracle块的sql文件,并希望从该块生成的输出(dbms_输出)显示在文本框中 到目前为止,我已经完成了调用sqlplus、执行文件以及通过消息框检索输出的任务。 但当我尝试对文本框执行同样的操作时,我得到了下面的运行时错误 System.InvalidOperationException未处理 Message=跨线程操作无效:控件“textB
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.5async
/wait
将解决您的问题,那么您正试图从另一个线程设置文本。否则,最好将类中的字符串设置为输出,并使用计时器轮询结果。或者您可以使用BeginInvoke
在GUI线程上运行一些代码(这可能是您最好的选择):我使用的是visual express c#2010。这将帮助我,如果你编辑我的代码,并提供正确的代码,因为我是一个新的程序员。非常感谢你的回复…我已经修改了它以包含所有明显需要的内容。非常感谢。。。它是有效的:)。到我的文本框的输出是一个没有新行的字符。块完成PL/SQL过程已成功完成。块完成PL/SQL过程已成功完成。你能推荐一下吗。我希望输出如下。block complete(新行)PL/SQL过程已成功完成。(新行)block complete(新行)PL/SQL过程已成功完成。@user3870268打印时只需添加新行即可(我已编辑文章)。如果我帮了忙,请记下我的答案!我正在打印新行,但它没有打印在文本框中。。同时让我知道如何将您标记为应答者:)方框是否标记为多行?当您选择它时,在框的右上角应该有一个复选框,您可以勾选?是,它被选中。我也尝试过富文本框。但结果是一样的(