C# 操作 Oracle小结
时间:2010-08-17 来源:扬帆起航
这几天打算做一个c#安装部署项目,附带要还原Oracle数据库,之前的想法是想在Web服务器上能够自动还原Oracle数据库(不管Web服务器是否已安装Oracle客户端或服务端),后来经过验证此法是行不通的,不过SqlServer就可以,它是可以调用Interop.SQLDMO.dll组件,但是Oracle的话需要调用SqlPlus或imp、Exp等工具,这样的话必须要安装Oracle,后来在网上找了几种Oracle免安装方式,有些是可以直接连Oracle服务器了,但是没imp、exp等工具,后来好不容易找了一个有imp、exp工具的,可以将数据导出来,但是我试了一下午导入(用自己开发的一个导入程序),结果试了一下午就是不行。表现出来的效果好像是死锁了,但是后来我直接用command命令一试,结果表明是我的免安装的Oracle环境问题。
无奈我想只能调整一下我的方案,在web服务器上安装时让用户自己选择安装项目(选安装网站),在数据库服务器选“安装数据库”。
今天主要实验的是用C#调用command命令行来执行Oracle的导入或执行Oracle 的 Sql操作:
如果想获取标准输出流或错误输出流时,在执行WaitForExit()方法时可能会导致死锁情况的发生,可以有几种方式
1. 异步读取流。
2.使用两个线程分别读取标准输出流和错误输出流。
1.异步读流:
private void Imp1()
{
string user;
string paw;
string server;
string excute, path;
try
{
user = txtUser.Text;
paw = txtPwd.Text; server = txtServer.Text; path = txtPath.Text;
excute = "imp" + " " + user + "/" + paw + "@" + server + " buffer=10000000 full=y " + "file = " + path + " log=imp.txt";
//excute = "sqlplus" + " " + user + "/" + paw + "@" + server + " @createUser.sql";
ProcessStartInfo pi = new ProcessStartInfo();
pi.FileName = "Imput.bat";
pi.UseShellExecute = false;
pi.RedirectStandardOutput = false;
pi.RedirectStandardError = true;
pi.RedirectStandardInput = false;
pi.CreateNoWindow = true;
pi.WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory;
Process p = new Process();
p.StartInfo = pi;
p.Start();
p.BeginErrorReadLine();//异步读取
p.WaitForExit();//等待程序执行完退出进程
p.Close();//关闭进程
MessageBox.Show("导入成功", "提示信息");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "提示信息");
}
}
----------------------------------------------------------------------------------------
2.使用线程
private void Imp2()
{
string user;
string paw;
string server;
string excute, path;
try
{
user = txtUser.Text;
paw = txtPwd.Text;
server = txtServer.Text;
path = txtPath.Text;
excute = "imp" + " " + user + "/" + paw + "@" + server + " buffer=10000000 full=y " + "file = " + path + " log=imp.txt";
Process p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
p.Start();
p.StandardInput.WriteLine(excute);
p.StandardInput.WriteLine("pause");
p.EnableRaisingEvents = true;
p.BeginOutputReadLine();//开始异步读取
//string error = p.StandardError.ReadToEnd(); //同步读取
ThreadStandardOutput t1 = new ThreadStandardOutput(p);
ThreadStandError t2 = new ThreadStandError(p);
Thread thread1 = new Thread(new ThreadStart(t1.Read));
Thread thread2 = new Thread(new ThreadStart(t2.Read));
thread1.Start();
thread2.Start();
StreamReader reader = p.StandardOutput;
string line = reader.ReadLine();//每次读取一行
while (!reader.EndOfStream)
{
richTextBox1.AppendText(line + " ");
MessageBox.Show(line);
richTextBox1.AppendText("\n");
line = reader.ReadLine();
}
p.WaitForExit();//等待程序执行完退出进程
p.Close();//关闭进程
MessageBox.Show("导入成功", "提示信息");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "提示信息");
}
}
/// <summary>
/// ThreadStandardOutput
/// </summary>
class ThreadStandardOutput
{
Process p;
public ThreadStandardOutput(Process p)
{
this.p = p;
}
public void Read()
{
int a = -1;
while ((a = p.StandardOutput.Read()) > 0)
{
//File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + "implog.txt", ((char)a).ToString());
}
Thread.CurrentThread.Abort();
}
}
/// <summary>
/// ThreadStandError
/// </summary>
class ThreadStandError
{
Process p;
public ThreadStandError(Process p)
{
this.p = p;
}
public void Read()
{
int a = -1;
while ((a = p.StandardError.Read()) > 0)
{
//File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + "implog.txt", ((char)a).ToString());
}
Thread.CurrentThread.Abort();
}
}
input.bat 内容:
imp testUser/123@ORCL buffer=10000000 full=y file=C:\sfsb_7_29.dmp log=C:\sfsb_7_29imp.txt
Insert.bat 内容:
sqlplus testuser/123@orcl11 '@c:\Insert.sql','@c:\Insert.sql'
Insert.Sql 内容
insert into testtab(Userid,username) values('user1','用户1');
insert into testtab(Userid,username) values('user2','用户2');
commit;
参考文章:
http://heisetoufa.javaeye.com/blog/323395
http://www.cnblogs.com/KissKnife/archive/2009/09/07/1561629.html
http://msdn.microsoft.com/zh-cn/library/system.diagnostics.process.standardoutput(VS.80).aspx