删除聚簇索引会从列中删除PK

时间:2011-03-17 17:57:51

标签: sql-server sql-server-2008

如果我删除聚集索引(在PK列上设置),它将从列定义中删除PK属性。什么交易?

如果我在表上有非聚集索引并删除聚簇索引,那么它不会从列定义中删除PK属性

1 个答案:

答案 0 :(得分:11)

我假设您是从GUI工具而不是从SQL语句执行此操作。 当您尝试删除已在PK上定义的聚簇索引时实际发生的情况,它将首先执行ALTER TABLE DROP CONSTRAINT,因为它无法对PK正在使用的索引执行DROP INDEX语句(见this MSDN article,第二段)。你也不应该使用Non-Clustered index这样做。

这是一个例子......我创建了一个Foo表:

CREATE TABLE foo (id int primary key, value varchar(50))

这会创建一个自动聚簇索引(即PK_foo_3213EXXXXXXXXX)

尝试从该工具(SQL Management studio)执行此操作: 右键单击该表中的PK_foo_3213EXXXXXXXX索引并执行脚本索引为 - > DROP to ...并看看它会产生什么......

实际上就是这样:

/****** Object:  Index [PK__foo__3213E83F7F60ED59]    Script Date: 03/17/2011 11:49:57 ******/
IF  EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[foo]') AND name = N'PK__foo__3213E83F7F60ED59')
ALTER TABLE [dbo].[foo] DROP CONSTRAINT [PK__foo__3213E83F7F60ED59]
GO

假设我是否像这样添加另一个索引(唯一的非群集):

/****** Object:  Index [test]    Script Date: 03/17/2011 11:55:46 ******/
CREATE UNIQUE NONCLUSTERED INDEX [test] ON [dbo].[foo] 
(
    [id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

并执行相同的操作(脚本为DROP),这是将生成的脚本:

/****** Object:  Index [test]    Script Date: 03/17/2011 11:54:48 ******/
IF  EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[foo]') AND name = N'test')
DROP INDEX [test] ON [dbo].[foo] WITH ( ONLINE = OFF )
GO

USE [dummy]
GO

注意区别(前一个是ALTER TABLE DROP CONSTRAINT,后面是DROP INDEX)。

如果您尝试强制SQL在PK聚集索引上执行此操作:

DROP INDEX [PK__foo__3213E83F7F60ED59] ON [dbo].[foo]

你会得到这个:

消息3723,级别16,状态4,第1行 索引'dbo.foo.PK_ foo _3213E83F7F60ED59'不允许使用显式DROP INDEX。它用于PRIMARY KEY约束实施。

因此,SQL被强制执行DROP CONSTRAINT。

我不确定您的第二个if语句是什么意思...如果您的意思是您已经在非聚集索引上定义了PK,并且您有另一个不是PK的聚簇索引并丢弃该聚簇索引。那么是......这就是将要发生的行为(你的PK约束不会被删除)。

为了好玩,尝试在非聚集索引上的PK上编写DROP INDEX脚本...并猜测它将生成什么脚本:)。提示提示...... ALTER TABLE .... DROP ... CONSTRAINT