【问题标题】:How to script a unique index with included columns using SQL Server Management Objects (SMO)?如何使用 SQL Server 管理对象 (SMO) 编写包含列的唯一索引?
【发布时间】:2016-02-12 07:00:19
【问题描述】:

我正在尝试使用 SQL Server Management Objects (SMO) 库来编写一个包含 included columns 的唯一非聚集索引的表创建脚本。

我希望它生成的脚本类似于:

CREATE TABLE [dbo].[testTable]
(
        [columnA] [int],
        [columnB] [int],
);

CREATE UNIQUE NONCLUSTERED INDEX [myIndex] 
ON [testTable] (A) INCLUDE (B)

我的问题是 SMO 在尝试编写包含列的唯一索引时会失败,但以下情况除外。似乎 SMO 认为我在表上创建的任何唯一索引都是使用 ADD CONSTRAINT 语句而不是 CREATE INDEX 生成的。我相信这就是它失败的原因,因为包含的列仅在索引中有效,而不是在约束中有效。这发生在版本 12 和 13 上。

Microsoft.SqlServer.Management.Smo.WrongPropertyValueException:无法在此索引类型上定义包含的列。
在 Microsoft.SqlServer.Management.Smo.Index.IndexScripter.ScriptColumn(IndexedColumn col, StringBuilder sb)
在 Microsoft.SqlServer.Management.Smo.Index.ConstraintScripter.ScriptColumn(IndexedColumn col, StringBuilder sb)
在 Microsoft.SqlServer.Management.Smo.Index.IndexScripter.ScriptColumns(StringBuilder sb)
在 Microsoft.SqlServer.Management.Smo.Index.IndexScripter.GetCreateScript()
在 Microsoft.SqlServer.Management.Smo.Index.GetDDL(ScriptingPreferences sp,布尔创建,布尔表创建)
在 Microsoft.SqlServer.Management.Smo.Index.ScriptDdl(StringCollection 查询、ScriptingPreferences sp、Boolean notEmbedded、Boolean createStatement)
在 Microsoft.SqlServer.Management.Smo.Table.GeneratePkUkInCreateTable(StringBuilder sb,ScriptingPreferences sp,ICollection 索引,布尔嵌入)
在 Microsoft.SqlServer.Management.Smo.Table.GetTableCreationScript(ScriptingPreferences sp, StringBuilder sb)
在 Microsoft.SqlServer.Management.Smo.Table.ScriptCreate(StringCollection 查询,ScriptingPreferences sp)
在 Microsoft.SqlServer.Management.Smo.SqlSmoObject.ScriptCreateInternal(StringCollection 查询、ScriptingPreferences sp、布尔型 skipPropagateScript)
在 Microsoft.SqlServer.Management.Smo.ScriptMaker.ScriptCreateObject(Urn urn,ScriptingPreferences sp,ObjectScriptingType& scriptType)
在 Microsoft.SqlServer.Management.Smo.ScriptMaker.ScriptCreate(Urn urn,ScriptingPreferences sp,ObjectScriptingType& scriptType)
在 Microsoft.SqlServer.Management.Smo.ScriptMaker.ScriptCreateObjects(IEnumerable1 urns)
at Microsoft.SqlServer.Management.Smo.ScriptMaker.ScriptUrns(List
1 orderedUrns)
在 Microsoft.SqlServer.Management.Smo.ScriptMaker.DiscoverOrderScript(IEnumerable1 urns)
at Microsoft.SqlServer.Management.Smo.ScriptMaker.ScriptWorker(List
1 urns,ISmoS​​criptWriter 作家)
在 Microsoft.SqlServer.Management.Smo.ScriptMaker.Script(SqlSmoObject[] 对象,ISmoS​​criptWriter 编写器)
在 Microsoft.SqlServer.Management.Smo.ScriptMaker.Script(SqlSmoObject[] 对象) 在 Microsoft.SqlServer.Management.Smo.Table.ScriptCreateInternal(StringCollection 查询,ScriptingPreferences sp)
在 Microsoft.SqlServer.Management.Smo.SqlSmoObject.CreateImpl()

这是我用来调试问题的 C# sn-p:

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 创建包含列的唯一非聚集索引?

【问题讨论】:

    标签: sql sql-server tsql smo unique-index


    【解决方案1】:

    尝试改变

    Index index = new Index(table, "myIndex") { IndexKeyType = IndexKeyType.DriUniqueKey };
    

    Index index = new Index(table, "myIndex")
    {
        IndexKeyType = IndexKeyType.None,
        IsUnique = true
    };
    

    【讨论】:

    • 感谢您的建议。我试过了,但它给出了错误“表'dbo.testTable'的创建失败。要完成此操作,请设置属性IndexKeyType。”。
    • @andre,如果您在索引定义中也分配IndexKeyType = IndexKeyType.None,如here 所述,None 用于“索引基于没有键约束的列” .
    • 你是对的。将 IndexKeyType 设置为 None 并将 IsUnique 设置为 true 就可以了!我的印象是 None 是键类型的默认值,我之前没想过自己设置它。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2014-12-16
    • 1970-01-01
    • 1970-01-01
    • 2012-04-03
    • 2012-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多