如果我删除聚集索引(在PK列上设置),它将从列定义中删除PK属性。什么交易?
如果我在表上有非聚集索引并删除聚簇索引,那么它不会从列定义中删除PK属性
答案 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