C#可以调用osql.exe来执行*.sql的SqlServer脚本文件执行脚本文件中的SQL语句实现创建表、视图、存储过程、增删改查数据等所有SqlServer操作。
一、C# 调用osql.exe执行sql脚本文件的方法【测试最稳定,使用命令行方式】
using System; using System.Diagnostics; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { //参数 string[] args = new string[5]; args[0] = "-U " + txtUserName.Text; //用户名 args[1] = "-P " + txtPassword.Text; //用户密码 args[2] = "-S " + txtServer.Text; //服务器 args[3] = "-d " + txtDatabase.Text; //数据库 args[4] = "-i " + AppDomain.CurrentDomain.BaseDirectory + "Install.sql"; //sql脚本路径 //执行 textBox1.Text = CommandLine("osql.exe", args); } #region 调用命令行工具 /// <summary> /// 调用命令行工具 /// </summary> /// <param name="name">命令行工具名称</param> /// <param name="args">可选命令行参数</param> /// <remarks>注意:所有命令行工具都必须保存于system32文件夹中</remarks> /// <returns></returns> private string CommandLine(string name, params string[] args) { return CommandLine(name, "", args); } /// <summary> /// 调用命令行工具 /// </summary> /// <param name="name">命令行工具名称</param> /// <param name="workingDirectory">设置工作目录</param> /// <param name="args">可选命令行参数</param> /// <remarks>注意:所有命令行工具都必须保存于system32文件夹中</remarks> /// <returns></returns> private string CommandLine(string name, string workingDirectory, params string[] args) { string returnValue = ""; using (Process commandline = new Process()) { try { commandline.StartInfo.UseShellExecute = false; commandline.StartInfo.CreateNoWindow = true; commandline.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; commandline.StartInfo.RedirectStandardOutput = true; commandline.StartInfo.FileName = name; commandline.StartInfo.WorkingDirectory = workingDirectory; //添加命令行参数 if (args.Length > 0) commandline.StartInfo.Arguments = string.Join(" ", args); commandline.Start(); commandline.WaitForExit(); returnValue = commandline.StandardOutput.ReadToEnd(); commandline.Close(); } catch { commandline.Dispose(); throw; } } return returnValue; } #endregion } }
二、C#读取.sql文件并执行文件中的sql
有些时候我们需要在程序中编写读取sql脚本文件并执行这些sql语句,但是我们在有些时候会遇到读出来的sql语句不能执行,其实不能执行并不是你的sql脚本文件有错误,而是去执行sql语句的时候,而是C#代码里面执行sql语句的代码对sql里面的一些标志字符不识别罢了,下面有两种方法可以实现读取sql文件并执行:
第一种方法是将sql脚本文件中的sql语句全部读取出来,然后使用C#代码去执行sql语句,但是这种方法的缺陷是:不能有Go标识符,还有不能执行创建视图的语句,如果有上述语句C#代码执行sql语句的时候就会出错,切记以上两点,废话不多说上代码:
方法一:C#读取sql文本内容后使用C#执行sql语句
/// <summary> /// 利用数组获取sql脚本文件中的sql语句 /// </summary> /// <param name="targetdir">路劲</param> /// <param name="dbname">数据库名</param> /// <returns></returns> public static ArrayList Getarraylist(string targetdir, string dbname) { ArrayList sqllist = new ArrayList(); try { System.IO.FileInfo FileInfo = new System.IO.FileInfo(targetdir + "kmsnew.sql"); string path = Path.Combine(targetdir, "kmsnew.sql"); string commandText = ""; string varLine = ""; StreamReader sr = new StreamReader(path, System.Text.Encoding.Default); while (sr.Peek() > -1) { varLine = sr.ReadLine(); varLine=varLine.Replace("[kms]","["+dbname+"]"); if (varLine == "") { continue; } if (varLine != "GO" && varLine != "go"&&varLine.Substring(0,1)!="/") { commandText += varLine; commandText += "\r\n"; } else { sqllist.Add(commandText); commandText = ""; } } //string line = sr.ReadToEnd(); sr.Close(); //line = line.Replace("[kms]", "[" + dbname + "]"); return sqllist; } catch (Exception e) { throw new InstallException(e.Message); } } //将获取到的数据传入这个函数就可以执行sql语句 public static void ExcuteSql(SqlConnection connectstring,Arraylist sql) { try { SqlTransaction varTrans = connectstring.BeginTransaction(); SqlCommand cmd = new SqlCommand(); cmd.Connection = connectstring; cmd.Transaction = varTrans; foreach(string sqlstring in sql) { if (sqlstring != null) { cmd.CommandText = sqlstring; cmd.ExecuteNonQuery(); } } varTrans.Commit(); } catch (Exception e) { throw new InstallException(e.Message); } }
方法二:使用osql.exe执行sql脚本
本人建议使用方法二,因为方法二没有方法一那么多限制条件,不论是什么sql语句,只要能在sqlserver中执行的语句,它全部都能执行,代码如下:
///<summary> ///利用osql实现执行sql脚本文件 /// </summary> //利用osql实现执行sql脚本文件 public static void excutesqlfile(string user,string pwd,string databasename,string targetdir) { System.Diagnostics.Process sqlProcess = new System.Diagnostics.Process(); sqlProcess.StartInfo.FileName = "osql.exe "; sqlProcess.StartInfo.Arguments = " -U "+数据库用户名+" -P "+数据库密码+" -d "+数据库名称+" -i "+文件路劲+"kmssql.sql"; sqlProcess.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; sqlProcess.Start(); sqlProcess.WaitForExit();//程序安装过程中执行 sqlProcess.Close(); }
三、C#如何导出SqlServer脚本
导出的方法本人只知道通过C#读取SqlServer数据遍历,拼接sql语句写入文件的方法。如果有人知道更好的 记得告诉我一下。
但这个方法要注意几个问题:
1、SQL脚本文件编码最好是存成GB2312的,而不是UTF-8,否则在使用osql.exe执行的时候会乱码报一堆错误。
在写入文件时候要加上编码
using (StreamWriter sw = new StreamWriter(path,System.Text.Encoding.GetEncoding("GB2312")))
{
sw.Write("This is the ");
sw.WriteLine(DateTime.Now);
}
如果想用UTF-8
StreamWriter sw=new StreamWriter("C:\\pp.txt", false, Encoding.UTF8);
其中,StreamWriter的参数如下:
public StreamWriter (
string path, // 文件路径
bool append, // 是否在末尾添加
Encoding encoding // 编码方式
)
2、如果在自行发现有异常,可以通过添加参数打印执行日志
osql -U sa -P 123456 -S 127.0.0.1 -d testdb -r -e -i "C:\sp_Insert_User.sql" -o "c:\ErrorInfo.txt"
四、附OSQL命令的参数说明:
[-U 登录 ID]
[-P 密码]
[-S 服务器]
[-H 主机名]
[-E 可信连接]
[-d 使用数据库名称]
[-l 登录超时值]
[-t 查询超时值]
[-h 标题]
[-s 列分隔符]
[-w 列宽]
[-a 数据包大小]
[-e 回显输入]
[-I 允许带引号的标识符]
[-L 列出服务器]
[-c 命令结束]
[-D ODBC DSN 名称]
[-q "命令行查询"]
[-Q "命令行查询" 并退出]
[-n 删除编号方式]
[-m 错误级别]
[-r 发送到 stderr 的消息]
[-V 严重级别]
[-i 输入文件]
[-o 输出文件]
[-p 打印统计信息]
[-b 出错时中止批处理]
[-X[1] 禁用命令,[退出的同时显示警告]]
[-O 使用旧 ISQL 行为禁用下列项]
五、批处理调用OSQL执行SQL脚本文件例子
例子:bat文件
rem =========================
rem 这是一个批处理调用OSQL的例子
OSQL /U sa /P sasa -S 127.0.0.1 -d testdb -r -i srcpit.sql -o C:\logs.txt
pause
评论回复