如何使用 SQL 服务器管理对象 (SMO) 编写包含列的唯一索引脚本?
How to script a unique index with included columns using SQL Server Management Objects (SMO)?
我正在尝试使用 SQL Server Management Objects (SMO) library to script a table creation with a unique non-clustered index that contains included columns。
我希望它生成的脚本类型类似于:
CREATE TABLE [dbo].[testTable]
(
[columnA] [int],
[columnB] [int],
);
CREATE UNIQUE NONCLUSTERED INDEX [myIndex]
ON [testTable] (A) INCLUDE (B)
我的问题是,当 SMO 尝试编写包含列的唯一索引脚本时,失败并出现以下异常。似乎 SMO 认为我在 table 上创建的任何唯一索引都将使用 ADD CONSTRAINT 语句而不是 CREATE INDEX 生成。我相信这就是它失败的原因,因为包含的列仅在索引中有效,在约束中无效。这发生在版本 12 和 13 上。
Microsoft.SqlServer.Management.Smo.WrongPropertyValueException: Cannot define an included column on this index type.
at Microsoft.SqlServer.Management.Smo.Index.IndexScripter.ScriptColumn(IndexedColumn col, StringBuilder sb)
at Microsoft.SqlServer.Management.Smo.Index.ConstraintScripter.ScriptColumn(IndexedColumn col, StringBuilder sb)
at Microsoft.SqlServer.Management.Smo.Index.IndexScripter.ScriptColumns(StringBuilder sb)
at Microsoft.SqlServer.Management.Smo.Index.IndexScripter.GetCreateScript()
at Microsoft.SqlServer.Management.Smo.Index.GetDDL(ScriptingPreferences sp, Boolean creating, Boolean tableCreate)
at Microsoft.SqlServer.Management.Smo.Index.ScriptDdl(StringCollection queries, ScriptingPreferences sp, Boolean notEmbedded, Boolean createStatement)
at Microsoft.SqlServer.Management.Smo.Table.GeneratePkUkInCreateTable(StringBuilder sb, ScriptingPreferences sp, ICollection indexes, Boolean embedded)
at Microsoft.SqlServer.Management.Smo.Table.GetTableCreationScript(ScriptingPreferences sp, StringBuilder sb)
at Microsoft.SqlServer.Management.Smo.Table.ScriptCreate(StringCollection queries, ScriptingPreferences sp)
at Microsoft.SqlServer.Management.Smo.SqlSmoObject.ScriptCreateInternal(StringCollection query, ScriptingPreferences sp, Boolean skipPropagateScript)
at Microsoft.SqlServer.Management.Smo.ScriptMaker.ScriptCreateObject(Urn urn, ScriptingPreferences sp, ObjectScriptingType& scriptType)
at Microsoft.SqlServer.Management.Smo.ScriptMaker.ScriptCreate(Urn urn, ScriptingPreferences sp, ObjectScriptingType& scriptType)
at Microsoft.SqlServer.Management.Smo.ScriptMaker.ScriptCreateObjects(IEnumerable1 urns)<br>
at Microsoft.SqlServer.Management.Smo.ScriptMaker.ScriptUrns(List
1 orderedUrns)
at Microsoft.SqlServer.Management.Smo.ScriptMaker.DiscoverOrderScript(IEnumerable1 urns)<br>
at Microsoft.SqlServer.Management.Smo.ScriptMaker.ScriptWorker(List
1 urns, ISmoScriptWriter writer)
at Microsoft.SqlServer.Management.Smo.ScriptMaker.Script(SqlSmoObject[] objects, ISmoScriptWriter writer)
at Microsoft.SqlServer.Management.Smo.ScriptMaker.Script(SqlSmoObject[] objects)
at Microsoft.SqlServer.Management.Smo.Table.ScriptCreateInternal(StringCollection query, ScriptingPreferences sp)
at Microsoft.SqlServer.Management.Smo.SqlSmoObject.CreateImpl()
这是我用来调试问题的 C# 片段:
static void Main(string[] args)
{
Database tmpDatabase = null;
try
{
tmpDatabase = new Database(new Server("(local)"), "myTempDb");
tmpDatabase.Create();
// create my table
Table table = new Table(tmpDatabase, "testTable");
table.Columns.Add(new Column(table, "columnA", DataType.Int));
table.Columns.Add(new Column(table, "columnB", DataType.Int));
// create my unique index and add key and included column
Index index = new Index(table, "myIndex") { IndexKeyType = IndexKeyType.DriUniqueKey };
index.IndexedColumns.Add(new IndexedColumn(index, "columnA"));
index.IndexedColumns.Add(new IndexedColumn(index, "columnB") { IsIncluded = true });
table.Indexes.Add(index);
try
{
table.Create();
var lines = table.Script(new ScriptingOptions() { Indexes = true });
foreach (var line in lines)
Console.WriteLine(line);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
if (e.InnerException != null)
Console.WriteLine(e.InnerException.Message);
}
Console.ReadKey();
}
finally
{
if (tmpDatabase != null) tmpDatabase.Drop();
}
}
我可以在此代码中更改什么以使 SMO 创建包含列的唯一非聚集索引?
尝试改变
Index index = new Index(table, "myIndex") { IndexKeyType = IndexKeyType.DriUniqueKey };
至
Index index = new Index(table, "myIndex")
{
IndexKeyType = IndexKeyType.None,
IsUnique = true
};
我正在尝试使用 SQL Server Management Objects (SMO) library to script a table creation with a unique non-clustered index that contains included columns。
我希望它生成的脚本类型类似于:
CREATE TABLE [dbo].[testTable]
(
[columnA] [int],
[columnB] [int],
);
CREATE UNIQUE NONCLUSTERED INDEX [myIndex]
ON [testTable] (A) INCLUDE (B)
我的问题是,当 SMO 尝试编写包含列的唯一索引脚本时,失败并出现以下异常。似乎 SMO 认为我在 table 上创建的任何唯一索引都将使用 ADD CONSTRAINT 语句而不是 CREATE INDEX 生成。我相信这就是它失败的原因,因为包含的列仅在索引中有效,在约束中无效。这发生在版本 12 和 13 上。
Microsoft.SqlServer.Management.Smo.WrongPropertyValueException: Cannot define an included column on this index type.
at Microsoft.SqlServer.Management.Smo.Index.IndexScripter.ScriptColumn(IndexedColumn col, StringBuilder sb)
at Microsoft.SqlServer.Management.Smo.Index.ConstraintScripter.ScriptColumn(IndexedColumn col, StringBuilder sb)
at Microsoft.SqlServer.Management.Smo.Index.IndexScripter.ScriptColumns(StringBuilder sb)
at Microsoft.SqlServer.Management.Smo.Index.IndexScripter.GetCreateScript()
at Microsoft.SqlServer.Management.Smo.Index.GetDDL(ScriptingPreferences sp, Boolean creating, Boolean tableCreate)
at Microsoft.SqlServer.Management.Smo.Index.ScriptDdl(StringCollection queries, ScriptingPreferences sp, Boolean notEmbedded, Boolean createStatement)
at Microsoft.SqlServer.Management.Smo.Table.GeneratePkUkInCreateTable(StringBuilder sb, ScriptingPreferences sp, ICollection indexes, Boolean embedded)
at Microsoft.SqlServer.Management.Smo.Table.GetTableCreationScript(ScriptingPreferences sp, StringBuilder sb)
at Microsoft.SqlServer.Management.Smo.Table.ScriptCreate(StringCollection queries, ScriptingPreferences sp)
at Microsoft.SqlServer.Management.Smo.SqlSmoObject.ScriptCreateInternal(StringCollection query, ScriptingPreferences sp, Boolean skipPropagateScript)
at Microsoft.SqlServer.Management.Smo.ScriptMaker.ScriptCreateObject(Urn urn, ScriptingPreferences sp, ObjectScriptingType& scriptType)
at Microsoft.SqlServer.Management.Smo.ScriptMaker.ScriptCreate(Urn urn, ScriptingPreferences sp, ObjectScriptingType& scriptType)
at Microsoft.SqlServer.Management.Smo.ScriptMaker.ScriptCreateObjects(IEnumerable1 urns)<br> at Microsoft.SqlServer.Management.Smo.ScriptMaker.ScriptUrns(List
1 orderedUrns)
at Microsoft.SqlServer.Management.Smo.ScriptMaker.DiscoverOrderScript(IEnumerable1 urns)<br> at Microsoft.SqlServer.Management.Smo.ScriptMaker.ScriptWorker(List
1 urns, ISmoScriptWriter writer)
at Microsoft.SqlServer.Management.Smo.ScriptMaker.Script(SqlSmoObject[] objects, ISmoScriptWriter writer)
at Microsoft.SqlServer.Management.Smo.ScriptMaker.Script(SqlSmoObject[] objects) at Microsoft.SqlServer.Management.Smo.Table.ScriptCreateInternal(StringCollection query, ScriptingPreferences sp)
at Microsoft.SqlServer.Management.Smo.SqlSmoObject.CreateImpl()
这是我用来调试问题的 C# 片段:
static void Main(string[] args)
{
Database tmpDatabase = null;
try
{
tmpDatabase = new Database(new Server("(local)"), "myTempDb");
tmpDatabase.Create();
// create my table
Table table = new Table(tmpDatabase, "testTable");
table.Columns.Add(new Column(table, "columnA", DataType.Int));
table.Columns.Add(new Column(table, "columnB", DataType.Int));
// create my unique index and add key and included column
Index index = new Index(table, "myIndex") { IndexKeyType = IndexKeyType.DriUniqueKey };
index.IndexedColumns.Add(new IndexedColumn(index, "columnA"));
index.IndexedColumns.Add(new IndexedColumn(index, "columnB") { IsIncluded = true });
table.Indexes.Add(index);
try
{
table.Create();
var lines = table.Script(new ScriptingOptions() { Indexes = true });
foreach (var line in lines)
Console.WriteLine(line);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
if (e.InnerException != null)
Console.WriteLine(e.InnerException.Message);
}
Console.ReadKey();
}
finally
{
if (tmpDatabase != null) tmpDatabase.Drop();
}
}
我可以在此代码中更改什么以使 SMO 创建包含列的唯一非聚集索引?
尝试改变
Index index = new Index(table, "myIndex") { IndexKeyType = IndexKeyType.DriUniqueKey };
至
Index index = new Index(table, "myIndex")
{
IndexKeyType = IndexKeyType.None,
IsUnique = true
};