ADO.NET和ExecuteNonQuery:如何使用DDL

时间:2010-06-23 14:56:18

标签: sql-server ado.net ddl executenonquery

我执行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不存在。它似乎在执行之前解析并验证它。

当我在Management Studio中执行所有内容时,我可以在语句之间放置GO,然后就可以了。当我将GO放入脚本时,ADO.NET会抱怨('GO'附近的语法不正确。)

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


根据约翰桑德斯的回答,如果有人有兴趣我的实施:

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);
    }
}

2 个答案:

答案 0 :(得分:2)

没有使用一个无数的ORM库来做到这一点?好的: - )

在运行进行结构更改的脚本时要完全安全,请使用SMO而不是SqlClient,并确保MARS未通过连接字符串打开(如果无论如何,SMO通常会抱怨)。查找 ServerConnection 类和ExecuteNonQuery - 当然是不同的DLL: - )

差异在于SMO dll将脚本按原样固定到SQL,因此它真正等同于在SSMS中运行它或通过isql cmd行运行它。每次遇到另一个小故障时,GO-s上的切片最终会变得更大,因为GO可以在多行注释的中间,可以有多个USE语句,一个脚本可以删除那个DB SqlCLient连接到 - oops :-)。我刚刚在我继承的代码库中杀死了一个这样的东西(在与MARS和MARS冲突的更复杂的脚本对生产代码有利但对管理员的东西不利之前)。

答案 1 :(得分:1)

您必须单独运行每个批次。特别是,要运行可能包含多个批次(“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
}