我执行SQL脚本以更改数据库架构。看起来像这样:

using (var command = connection.CreateCommand())
{
    command.CommandText = script;
    command.ExecuteNonQuery();
}

此外,这些命令是在事务中执行的。

脚本看起来像这样:

Alter Table [TableName]
ADD [NewColumn] bigint NULL

Update [TableName]
SET [NewColumn] = (SELECT somevalue FROM anothertable)

我有一个错误,因为 NewColumn 不存在。它似乎可以在执行之前对其进行解析和验证。

当我在管理工作室中执行全部内容时,我可以说 GO 在陈述之间,然后起作用。当我放 GO 在脚本中,Ado.net抱怨(“ Go”附近的语法不正确)。

我可以将脚本分为单独的脚本并在单独的命令中执行,这将很难处理。我可以在每个 GO, ,我自己解析剧本。我只是认为应该有一个更好的解决方案,而且我不了解一些东西。这样的脚本应该如何执行?


根据约翰·桑德斯(John Saunders)的回答,如果有人感兴趣,我的实施是:

List<string> lines = new List<string>();
while (!textStreamReader.EndOfStream)
{
    string line = textStreamReader.ReadLine();
    if (line.Trim().ToLower() == "go" || textStreamReader.EndOfStream)
    {
        ExecuteCommand(
            string.Join(Environment.NewLine, lines.ToArray()));

        lines.Clear();
    }
    else
    {
        lines.Add(line);
    }
}
有帮助吗?

解决方案

您必须单独运行每个批次。特别是,要运行一个可能包含多个批次的脚本(“ GO”关键字),您必须在“ GO”关键字上划分脚本。

未经测试:

string script = File.ReadAllText("script.sql");
string[] batches = script.Split(new [] {"GO"+Environment.NewLine}, StringSplitOptions.None);
foreach (string batch in batches)
{
    // run ExecuteNonQuery on the batch
}

其他提示

不使用Umpteen Orm库之一来做到这一点?好的 :-)

在运行进行结构更改的脚本时要完全安全,请使用SMO而不是SQLClclient,并确保不会通过连接字符串打开火星(无论如何,SMO通常会抱怨)。寻找 ServerConnection 课堂和执行者 - 当然不同的DLL :-)

差异是smo dll将脚本按原样划分为sql,因此在SSMS或通过ISQL CMD行中运行它是真正等效的。每次遇到另一个小故障时,go-s的切片最终都会成长为更大的扫描(例如,可以在多行评论中中间,可以有多种用法语句,脚本可以丢弃该db的DB sqlclient连接到-OOPS :-)。我刚刚在我继承的代码库中杀死了一件事情(在与火星和火星发生冲突后,对生产代码有益,但对管理员的东西不利)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top