如何使用c#执行一个.SQL脚本文件

知道91 | 问题 | 2015-09-07 | 阅读:4665

我确信这个问题已经回答, 但是我无法找到答案。 使用搜索工具。

使用c#我想运行一个.sql文件。 sql文件包含多个sql语句, 其中一些被拆分到多个行。 我尝试在文件中读取并尝试执行该文件使用ODP.Net ... 不过我不认为ExecuteNonQuery是真正用于执行这里操作。

所以我尝试使用sqlplu通过产生一个进程... 但是, 除非我繁殖过程和设置要UseShellExecute sqlplu会挂起, 永远不退出。 以下是代码, 没有工作。

Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "sqlplus";
p.StartInfo.Arguments = string.Format("xx/xx@{0} @{1}", in_database, s);
p.StartInfo.CreateNoWindow = true;

bool started = p.Start();
p.WaitForExit();

WaitForExit从不返回... 。 除非我UseShellExecute设置为真。 副作用UseShellExecute是, 你可以捕获输出重定向。

答案:

之前的代码示例, 可以避免死锁的条件通过调用p.StandardOutput.ReadToEnd p.WaitForExit. 会导致一个死锁条件。 如果父进程调用之前p.WaitForExit p.StandardOutput.ReadToEnd和子进程写入足够的文本以填充重定向流。 父进程将无限期地等待子进程退出。 子进程将无限期地等待父进程读取从完整StandardOutput流。 会出现类似的问题。 当同时读取所有文本从标准输出和标准错误流。 例如, 下面的C#的代码以上执行读取操作流。

将代码插入到这里:

Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "sqlplus";
p.StartInfo.Arguments = string.Format("xxx/xxx@{0} @{1}", in_database, s);

bool started = p.Start();
// important ... read stream input before waiting for exit.
// this avoids deadlock.
string output = p.StandardOutput.ReadToEnd();

p.WaitForExit();

Console.WriteLine(output);

if (p.ExitCode != 0)
{
	Console.WriteLine( string.Format("*** Failed : {0} - {1}",s,p.ExitCode));
	break;
}