【问题标题】:How to drop a Clustered Index on a table if it exists and add a new Clustered Index?如果存在,如何在表上删除聚集索引并添加新的聚集索引?
【发布时间】:2020-03-02 12:17:21
【问题描述】:

我正在一个表上创建聚集索引,如果它已经存在则删除。

我正在使用这个查询。

DROP INDEX IF EXISTS CLX_Enrolment_StudentID_BatchID
ON Enrollment
CREATE INDEX CLX_Enrolment_StudentID_BatchID
ON Enrollment(Studentid, BatchId ASC);

现在,我想知道这里创建了哪个集群:- 这是集群还是非集群?

CREATE INDEX CLX_Enrolment_StudentID_BatchID
ON Enrollment(Studentid, BatchId ASC);

因为使用:-

DROP clustered INDEX IF EXISTS CLX_Enrolment_StudentID_BatchID
ON Enrollment 

我收到此错误:-

Incorrect syntax near the keyword 'clustered'.

而且,如果我使用:-

DROP INDEX IF EXISTS CLX_Enrolment_StudentID_BatchID
ON Enrollment
go
CREATE clustered INDEX CLX_Enrolment_StudentID_BatchID
ON Enrollment(Studentid, BatchId ASC); 

我收到此错误:-

Cannot create more than one clustered index on table 'Enrollment'. Drop the existing clustered index 'PK__enrollme__DE799CE1E4649295' before creating another.

现在,我想知道在我的第二个查询中创建了哪个索引。而且,如果两者都没有被创建,那么如何删除聚集索引(如果存在)并创建一个新索引。

【问题讨论】:

  • 由于现有的聚集索引是主键索引,在创建新的聚集索引之前需要使用ALTER TABLE...DROP CONSTRAINTALTER TABLE...ADD CONSTRAINT将现有的主键索引改为非聚集索引。跨度>

标签: sql sql-server-2008 indexing


【解决方案1】:

您可以尝试使用IF EXISTS语法检查sys.indexes表是否包含索引。

IF EXISTS(
    SELECT * 
    FROM sys.indexes 
    WHERE name='CLX_Enrolment_StudentID_BatchID' AND OBJECT_ID = OBJECT_ID('Enrollment')
)
BEGIN
    DROP INDEX CLX_Enrolment_StudentID_BatchID ON [dbo].[Enrollment]
END
GO

CREATE clustered INDEX CLX_Enrolment_StudentID_BatchID
ON Enrollment(Studentid, BatchId ASC); 

但我认为您的错误消息中有一个索引PK__enrollme__DE799CE1E4649295

修改

如果你想DROP自动PK或聚集索引,你可以尝试使用动态sql创建脚本并使用sp_executesql执行。

DECLARE @sql NVARCHAR(500),
        @TableName VARCHAR(50) = 'Enrollment',
        @Para NVARCHAR(500)='@TableName VARCHAR(50)'

SELECT @sql = CONCAT('ALTER TABLE ',@TableName,' DROP CONSTRAINT ',name)
FROM sys.indexes 
WHERE OBJECT_ID = OBJECT_ID(@TableName) AND type_desc = 'CLUSTERED' AND is_primary_key = 1
EXEC sp_executesql @sql,@Para,@TableName

SELECT @sql = CONCAT('DROP INDEX ',name,' ON dbo.',@TableName)
FROM sys.indexes 
WHERE OBJECT_ID = OBJECT_ID(@TableName) AND type_desc = 'CLUSTERED'

EXEC sp_executesql @sql,@Para,@TableName

如果您的表已经包含PK,您需要使用ALTER TABLE .... DROP CONSTRAINT 而不是drop index

【讨论】:

  • 我认为在创建表时我已将 StudentId 和 BatchId 添加为 Primary_Key。所以,这可能是它显示的一个原因 - 在创建另一个或其他任何内容之前删除现有的聚集索引 'PK__enrollme__DE799CE1E4649295'?
  • 在我的索引描述中,它显示:-- 位于 PRIMARY 上的集群的、唯一的、主键
  • @SumitTiwary 好的,如果您的表格已经包含PK,我将编辑我的答案,您需要使用ALTER TABLE .... DROP CONSTRAINT 而不是drop index
猜你喜欢
  • 1970-01-01
  • 2013-08-07
  • 2016-08-30
  • 2018-08-04
  • 2018-02-17
  • 2011-10-03
  • 2015-10-13
  • 1970-01-01
相关资源
最近更新 更多