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

C# 使用C在sql Server上执行sql文件#,c#,sql,sql-server,C#,Sql,Sql Server,我正在尝试创建一个在sql Server数据库上运行.sql文件的方法 我的密码是: SqlConnection dbCon = new SqlConnection(connstr); FileInfo file = new FileInfo(Server.MapPath("~/Installer/JobTraksDB.sql")); StreamReader fileRead = file.OpenText(); string script = fileRead.ReadToEnd(); fi

我正在尝试创建一个在sql Server数据库上运行.sql文件的方法

我的密码是:

SqlConnection dbCon = new SqlConnection(connstr);
FileInfo file = new FileInfo(Server.MapPath("~/Installer/JobTraksDB.sql"));
StreamReader fileRead = file.OpenText();
string script = fileRead.ReadToEnd();
fileRead.Close();

SqlCommand command = new SqlCommand(script, dbCon);
try
{
    dbCon.Open();
    command.ExecuteNonQuery();
    dbCon.Close();
}
catch (Exception ex)
{
    throw new Exception("Failed to Update the Database, check your Permissions.");
}
但我不断地发现关于“关键字“GO”附近语法错误”的错误 我的SQL文件是这样开始的:(由SQL Management Studio生成)


我应该如何执行此脚本?

GO
不是一个T-SQL语句。这是一个提示,提示客户机工具(如
sqlcmd
或managementstudio)拆分语句并将它们作为单独的批发送。他们在自己的行上使用
GO
命令作为标记来指示批次的结束。您不应该将文件作为一个整体发送到SQL Server

旁注:您可以使用一种方法来代替这三行。

我们就是这样做的:

    protected virtual void ExecuteScript(SqlConnection connection, string script)
    {
        string[] commandTextArray = System.Text.RegularExpressions.Regex.Split(script, "\r\n[\t ]*GO");

        SqlCommand _cmd = new SqlCommand(String.Empty, connection);

        foreach (string commandText in commandTextArray)
        {
            if (commandText.Trim() == string.Empty) continue;
            if ((commandText.Length >= 3) && (commandText.Substring(0, 3).ToUpper() == "USE"))
            {
                throw new Exception("Create-script contains USE-statement. Please provide non-database specific create-scripts!");
            }

            _cmd.CommandText = commandText;
            _cmd.ExecuteNonQuery();
        }

    }

使用一些文件读取功能加载脚本的内容

如果您愿意包含两个SMO DLL,可以使用几行代码执行脚本:

using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;

    public void Exec(string script)
    {
        using (var conn = new SqlConnection(ConnString))
        {
            var server =  new Server(new ServerConnection(conn));
            server.ConnectionContext.ExecuteNonQuery(script, ExecutionTypes.ContinueOnError);
        }
    }
SMO库处理GO问题,因此您不必这样做。您将需要引用以下程序集:

Microsoft.SqlServer.ConnectionInfo.dll

Microsoft.SqlServer.Management.Sdk.Sfc.dll


Microsoft.SqlServer.Smo.dll

好的,那么执行批创建表功能的最佳方法是什么?(这适用于web安装程序)最简单的方法是将文件按包含
GO
命令的行分割,并以循环的方式将每个部分发送到SQL Server。然而,我认为您正在重新发明轮子,因为一些开源项目(例如DotNetNuke)在安装时使用了类似的技术。你可以查他们的来源。查我的答案。代码示例完美地完成了这项工作。我知道有一些开源web安装程序,但这几乎是我所需要的全部。。。谢谢你们的回答,伙计们!我可以看到一个bug:假设我有一个名为
sp
的过程,脚本是
“sp”
commandText.Substring(0,3)
将抛出一个
IndexOutOfRangeException
@Mehrdad:是的,常见错误,假设String.Substring(0,xxx)的工作方式与VB函数Left(xxx)完全相同:-)
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;

    public void Exec(string script)
    {
        using (var conn = new SqlConnection(ConnString))
        {
            var server =  new Server(new ServerConnection(conn));
            server.ConnectionContext.ExecuteNonQuery(script, ExecutionTypes.ContinueOnError);
        }
    }