【问题标题】:Generated Script via SMO can't be executed通过 SMO 生成的脚本无法执行
【发布时间】:2018-08-06 15:08:05
【问题描述】:

我正在使用 Smo 创建现有数据库的 SQL 脚本。出于测试目的,我删除了我的数据库并将脚本复制到一个新查询中以再次创建它。 不幸的是,这个过程会产生错误。

'CREATE VIEW' must be the first statement in a query batch

由于我创建了多个视图,因此此错误在 SQL Server Management Studio 的消息选项卡上多次显示。 当我寻找解决方案时,我发现“创建视图”之前的关键字“Go”显然丢失了。 “ScriptingOptions”类中是否包含在生成的脚本中附加“GO”的选项?

代码:

public void GenerateSQLScripts(string dbName)
    {

        StringBuilder sb = new StringBuilder();
        Server server = new Server(SqlServer);
        Database db = server.Databases[dbName];


        var scriptopt = new ScriptingOptions();
        scriptopt.TargetServerVersion = SqlServerVersion.Version105; // Windows 2008 R2
        scriptopt.AnsiPadding = true;
        scriptopt.WithDependencies = true;
        scriptopt.IncludeHeaders = true;
        scriptopt.SchemaQualify = true;
        scriptopt.ExtendedProperties = true;
        scriptopt.TargetDatabaseEngineType = DatabaseEngineType.Standalone;
        scriptopt.IncludeDatabaseContext = true;
        scriptopt.ScriptDrops = false;
        scriptopt.ScriptData = false;
        scriptopt.ScriptSchema = true;
        scriptopt.DriAllConstraints = true;
        scriptopt.DriForeignKeys = true;
        scriptopt.Indexes = true;
        scriptopt.DriPrimaryKey = true;
        scriptopt.DriUniqueKeys = true;
        scriptopt.DriChecks = true;
        scriptopt.AllowSystemObjects = false;
        scriptopt.AppendToFile = false;

        // script Tables
        foreach (Table t in db.Tables)
        {
            if (!t.IsSystemObject)
            {
                StringCollection sc = t.Script(scriptopt);
                foreach (string s in sc)
                {
                    sb.AppendLine(s);
                }
            }

        }

        //Script Stored Procedures
        foreach (StoredProcedure sp in db.StoredProcedures)
        {
            if (!sp.IsSystemObject)
            {
                var sc = sp.Script(scriptopt);
                foreach (string s in sc)
                {
                    sb.AppendLine(s);
                }
            } 

        }

        //Views
        foreach(View v in db.Views){
            if (!v.IsSystemObject)
            {
                StringCollection sc = v.Script(scriptopt);
                foreach (string s in sc)
                {
                    sb.AppendLine(s);
                }
            }

        }
        File.WriteAllText(Path, sb.ToString());

    }

【问题讨论】:

  • 其实GO不是关键字。它是 SSMS 中的默认批处理分隔符。它几乎可以用任何东西代替。不确定如何让 SMO 在生成的脚本中包含批处理分隔符。
  • @SeanLange 不知道,指的是这个问题:stackoverflow.com/questions/13340332/…
  • 你看文档了吗?似乎scriptbatchterminator 正是这样做的。
  • @SMor 感谢您的建议,但我又遇到了同样的错误。该脚本的行数也与激活该选项之前的行数相同。

标签: c# sql-server smo


【解决方案1】:

您要查找的属性称为“NoCommandTerminator”。将其设置为 false,您应该会很好。 我通过反复试验发现了这一点。实际上我也在使用 SMO,并且我正在将 ScriptingOptions 序列化为 XML 文件,以便以后能够更改它。在我的配置中我也说明了帮助,如何配置它,这一行是我为添加 GO 语句而写的:

  <NoCommandTerminator>false</NoCommandTerminator> <!-- Should we include a GO between statements? -->

【讨论】:

    【解决方案2】:

    坏消息,你是 SOL

    无论任何选项/标志如何,批处理终止符都只会进入文件:(

    我想出的唯一方法是设置 Options.ToFileOnly = $true,将其编写到临时位置并获取内容

    所以是的,MS 决定输出文件和字符串集合包含不同的东西。

    【讨论】:

      【解决方案3】:

      哇,看看有人构建了相同的工具,这让我很兴奋。 我的经验是您需要在创建脚本中手动附加 GO 关键字。如果您的脚本包含 Go 关键字,则无法由 SqlConnection 执行 并且只能由 SMO ConnectionContext 执行 例如

      smoServer.ConnectionContext.BeginTransaction();
      var result = smoServer.ConnectionContext.ExecuteNonQuery(_createViewScript);
      smoServer.ConnectionContext.CommitTransaction();
      

      【讨论】:

        猜你喜欢
        • 2013-08-07
        • 1970-01-01
        • 2023-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-26
        • 2011-07-03
        • 1970-01-01
        相关资源
        最近更新 更多