2011-03-17 69 views
2

PK。這是怎麼回事?卸下簇索引去除

如果我有表上的非聚集索引和刪除了聚集索引那麼它不會刪除列定義

+1

什麼是聚集索引的定義,你怎麼去除呢? – JNK 2011-03-17 18:02:45

+0

只需將ID列自動增量設置爲PK即可。設置PK時會自動創建羣集索引,並使用「唯一」複選框和選擇ID列手動創建羣集索引 – 2011-03-17 18:11:39

回答

10

我假設你的PK屬性從GUI工具,而不是從這樣做SQL語句。 實際發生的,當您嘗試刪除已在PK中定義的聚集索引,它會做ALTER TABLE DROP CONSTRAINT第一,因爲它無法做到對正在使用的PK的索引DROP INDEX語句(見this MSDN article,第二段)。您也不應該能夠使用非聚集索引來做到這一點。

下面是一個例子...我創建了一個富表:

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

這將創建一個自動聚集索引(即PK_foo_3213EXXXXXXXXX)

嘗試從工具做到這一點(SQL管理工作室): 右鍵單擊該表格中的PK_foo_3213EXXXXXXXX指數和做腳本索引 - >下降到...,看看它會產生...

它實際上是這樣的:

/****** 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 

,做同樣的(腳本下降到),這是將要生成的腳本:

/****** 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行 一個明確的DROP索引'dbo.foo.PK_ foo _3213E83F7F60ED59'不允許使用INDEX。它被用於PRIMARY KEY約束執行。

因此SQL被迫做DROP約束來代替。

我不確定你的意思是你的第二條語句......如果你的意思是你已經在非聚集索引上定義了一個PK,並且你有另一個不是PK的聚集索引並且刪除了該聚集索引。 ..然後是...那是將會發生的行爲(你的PK約束不會被丟棄)。

爲了好玩起見,儘量腳本DROP INDEX上是一個非聚集索引的PK ...並猜測它會產生什麼樣的腳本:)。提示提示... ALTER TABLE .... DROP ...約束