无法执行通过 SMO 生成的脚本



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

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

由于我正在创建多个视图,因此在SQLServerManagementStudio的消息选项卡上会多次显示此错误。当我寻找解决方案时,我发现"创建视图"之前的关键字"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());
}

您要查找的属性名为"NoCommandTerminator"。设置为false,你就应该是好的。我通过反复试验发现了这一点。事实上,我也在使用SMO,我正在将ScriptingOptions序列化为XML文件,以便以后能够更改它。在我的配置中,我还提到了帮助,如何配置它,这一行是我为添加GO语句而写的:

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

坏消息,你是SOL

批处理终止符只进入文件,而不考虑任何选项/标志:(

我唯一能想到的方法是设置Options.ToFileOnly=$true,将其脚本化到一个临时位置并获取内容

是的,MS已经决定输出文件和字符串集合包含不同的内容。

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

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

最新更新