使用C#在SQL Server上执行sql文件

时间:2011-01-26 18:04:19

标签: c# sql-server-2005 sql-server-2008 stored-procedures installation

我有许多程序,视图,函数等文件。

我想在SQL Server 2005/2008上的相应数据库中执行这些文件(创建组件)。

另外一点是我想用C#执行它们。

另一点需要提及的是,我希望应用程序能够在远程SQL Server上执行此文件。客户机也可能没有osql,sqlcmd命令工具。

有人可以指导我。

5 个答案:

答案 0 :(得分:7)

这取决于它们是什么类型的文件。例如,如果他们包含实际的T-SQL命令(并且不是您运行的文件,例如SSMS,它将包含批处理像GO这样的分隔符,然后你只需要创建一个连接,一个命令,然后读取文件的内容并使用它来填充命令的CommandText属性。

例如:

void ExecuteFile(string connectionString, string fileName)
{
    using(SqlConnection conn = new SqlConnection(connectionString))
    {
        string data = System.IO.File.ReadAllText(fileName);

        conn.Open();

        using(SqlCommand cmd = conn.CreateCommand())
        {
            cmd.CommandText = data;
            cmd.ExecuteNonQuery();
        }
    }
}

如果是批处理文件,则需要将文件拆分为单独的批处理并单独处理。最简单的方法就是使用string.Split,但请记住,它在分割时不会尊重SQL解析规则(例如,如果GO出现在SQL语句中,它将拆分命令分为两批,显然会失败)。

更一般地说,您可以通过以下方式修改代码来查看您需要执行的操作:

string[] batches = SplitBatches(System.IO.File.ReadAllText(fileName));

conn.Open();

using(SqlCommand cmd = conn.CreateCommand())
{
    foreach(string batch in batches)
    {
        cmd.CommandText = batch;
        cmd.ExecuteNonQuery();
    }
}

名为SplitBatches的函数的实现取决于您。

答案 1 :(得分:3)

通常,最简单的方法是在“GO”语句中拆分脚本并分别执行每个项目。如果脚本在注释中包含GO语句,则此解决方案将不起作用。

private readonly Regex _sqlScriptSplitRegEx = new Regex( @"^\s*GO\s*$", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Compiled );
public void ExecuteSqlScript( string scriptText )
{
    if ( string.IsNullOrEmpty( scriptText ) )
        return;

    var scripts = _sqlScriptSplitRegEx.Split( scriptText );
    using ( var conn = new SqlConnection( "connection string" ) )
    {
        using ( var ts = new TransactionScope( TransactionScopeOption.Required, new TimeSpan( 0, 10, 0 ) ) )
        {
            foreach ( var scriptLet in scripts )
            {
                if ( scriptLet.Trim().Length == 0 )
                    continue;

                using ( var cmd = new SqlCommand( scriptLet, conn ) )
                {
                    cmd.CommandTimeout = this.CommandTimeout;
                    cmd.CommandType = CommandType.Text;
                    cmd.ExecuteNonQuery();
                }
            }

            ts.Complete();
        }
    }
}

答案 2 :(得分:2)

通常,您只需要使用SqlCommand.ExecuteNonQuery执行它们,一次一批。这使您无需使用当前设置的批处理分隔符(通常为GO)将脚本拆分为批处理。免费库dbutilsqlcmd可用于处理SQL脚本,因为它不仅处理分隔符,还处理SQLCMD扩展(:setvar:connect等)。

答案 3 :(得分:0)

使用标准ADO将“正常工作” - 例如,可以使用SqlCommand.ExecuteNonQuery发送SQL DDL。

...但我建议使用数据库项目(使用远程登台部署或VSDBCMD)或其中一个工具,如SQLCMD(可能与PowerShell脚本:-)或SQL Management Studio等一起使用。它们是为这类东西而设计的。

答案 4 :(得分:0)

您可以使用TextReader读取命令,然后使用带有TextReader结果的ExecuteNonQuery作为命令。