我确信这个问题已经回答, 但是我无法找到答案。 使用搜索工具。
使用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; }