极品分享

C# 调用osql.exe执行sql脚本文件创建数据库表等操作

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







2017-04-26 0 /
NET学习
/
标签: 

评论回复

回到顶部