无法从表中删除唯一索引。

9
当我运行这个查询时:
ALTER TABLE "dbo"."ROOM" DROP INDEX "UNIQUE";

我收到了以下这条消息:

错误 1018:'INDEX' 附近有不正确的语法。如果这是作为表提示的一部分,则现在需要使用带括号的 WITH 关键字。请参阅 SQL Server Books Online 以获取正确的语法。

唯一索引的名称是 UNIQUE,我认为这就是问题所在,因为它是一个自动生成的名称(用于创建此索引的 SQL Server 客户端)。这是创造表句子:

CREATE TABLE "ROOM" (
    "ID" BIGINT NOT NULL DEFAULT NULL,
    //the rest of the columns...
    "ROOM" VARCHAR(100),
    UNIQUE INDEX "UNIQUE" ("ROOM")
)
;

您有没有想过如何删除这个索引?我知道可以删除整个表并重新创建,但我想避免这种情况发生。


5
唯一索引的名称是“UNIQUE”,这个名字确实不太好。我会使用idx_room_roomidxu_room_room作为索引名称。 - Gordon Linoff
2
为什么你将ID列定义为NOT NULL,但默认值却是NULL?这完全没有任何意义。这个东西看起来需要进行彻底的重新设计。 - Sean Lange
3
我很愿意打赌,几乎可以确定 SQL Server 没有为你的索引自动生成名为“Unique”的名称。 - Tab Alleman
完全正确。但是创建表可能是由我正在使用的SQL服务器客户端自动生成的。 - Perimosh
2个回答

21

您需要使用以下语句:

DROP INDEX [UNIQUE] ON dbo.Room 

你需要删除此索引,同时也要定义此索引所在的表...由于它的名称是SQL保留关键字,你需要将其放入方括号 ([UNIQUE])。

更多详细信息,请参见官方MSDN文档中有关 DROP INDEX 的说明

更新:如果此语句不起作用,则表示该索引实际上并不被称为UNIQUE

通过这个语句检查在Room表上定义了哪些索引:

SELECT * 
FROM sys.indexes 
WHERE object_id=OBJECT_ID('dbo.Room')

查看 Name 列 - 然后使用相应的实际索引名称删除该索引。

更新#2:好的,所以你确实有一个唯一约束条件,这是由那个唯一索引强制执行的。因此,为了摆脱它,首先需要找出该约束条件的名称和所在的表:

SELECT 
    name, 
    TableName = OBJECT_NAME(parent_object_id)
FROM sys.key_constraints
WHERE type = 'UQ'

一旦您获得了这两个信息,您现在可以放弃该约束:

ALTER TABLE (TableName)
DROP CONSTRAINT (ConstraintName)

然后您的唯一索引也将不复存在。


然后,使用以下命令检查Room上的索引实际名称:SELECT * FROM sys.indexes WHERE object_id=OBJECT_ID('dbo.Room') - 我怀疑索引名称并不是 UNIQUE....请使用适当的、实际的索引名称... - marc_s
3
说“没起作用”比说出你收到了什么错误信息或其他意外结果要少得多。 - Tab Alleman
同样的错误Tab Alleman。我试图提取索引名称。但是这些名称并不是很描述性的。我不确定应该删除哪一个。我可以看到有一列名为“is_unique_constraint”,只有一个设置为true。也许那个是我要找的? - Perimosh
好的,如果你的唯一索引执行了唯一约束,那么你需要找出这个约束的名称,然后删除该约束(而不是索引)。 - marc_s
@Perimosh:我更新了我的回复,包括如何查找您有哪些唯一约束条件以及如何删除它(这也将在后台删除唯一索引)。 - marc_s
显示剩余2条评论

0

第一步,获取索引

select schema_name(t.schema_id) + '.' + t.[name] as table_view, 
    case when t.[type] = 'U' then 'Table'
        when t.[type] = 'V' then 'View'
        end as [object_type],
    case when c.[type] = 'PK' then 'Primary key'
        when c.[type] = 'UQ' then 'Unique constraint'
        when i.[type] = 1 then 'Unique clustered index'
        when i.type = 2 then 'Unique index'
        end as constraint_type, 
    c.[name] as constraint_name,
    substring(column_names, 1, len(column_names)-1) as [columns],
    i.[name] as index_name,
    case when i.[type] = 1 then 'Clustered index'
        when i.type = 2 then 'Index'
        end as index_type
from sys.objects t
    left outer join sys.indexes i
        on t.object_id = i.object_id
    left outer join sys.key_constraints c
        on i.object_id = c.parent_object_id 
        and i.index_id = c.unique_index_id
   cross apply (select col.[name] + ', '
                    from sys.index_columns ic
                        inner join sys.columns col
                            on ic.object_id = col.object_id
                            and ic.column_id = col.column_id
                    where ic.object_id = t.object_id
                        and ic.index_id = i.index_id
                            order by col.column_id
                            for xml path ('') ) D (column_names)
where is_unique = 1
and t.is_ms_shipped <> 1 and t.[name]='table name'
order by schema_name(t.schema_id) + '.' + t.[name]

第二步,删除索引。
DROP INDEX [INDEXES NAME] ON dbo.[TABLE NAME] 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接