Change a Primary Key from Nonclustered to Clustered

前端 未结 3 616
闹比i
闹比i 2020-12-23 12:02

Suppose I have an SQL Server 2005 table, TableX, with 2 indexes on it:

PK_TableX = PRIMARY KEY NONCLUSTERED on FieldA
IX_TableX_FieldB = CLUSTERED on Fiel

3条回答
  •  滥情空心
    2020-12-23 12:18

    I know this is old but this will script out all the FK drops, the pk drop, the pk recreate, the FK recreates. Replace MYTABLE with your table name.

       IF  EXISTS (SELECT * FROM sys.tables WHERE object_id = OBJECT_ID(N'[dbo].[FKAgainstTableList]'))
    BEGIN 
        DROP TABLE FKAgainstTableList
    END
    --CREATE TABLE FKAgainstTableList (ForeignKey VARCHAR(30),[Table] VARCHAR(30))
    DECLARE @PKTableName VARCHAR(100), 
            @PKName varchar(100),
            @FKName varchar(100),
            @sql varchar(max),
            @PKcolumnName varchar(30),
            @table VARCHAR(100),
            @FKColumnName VARCHAR(100), 
            @parentColumnNumber int
    SET @PKTableName = 'MYTABLE'
    set @PKName = (SELECT name FROM sys.indexes WHERE OBJECT_NAME(object_id) = @PKTableName AND is_primary_key = 1)
    set @PKcolumnName = (SELECT name FROM sys.columns WHERE OBJECT_NAME(object_id) = @PKTableName AND is_identity =1)
    PRINT @PKcolumnName
    
     SELECT  OBJECT_NAME(sys.foreign_key_columns.parent_object_id) [Table],sys.columns.name [FKColumnName],sys.foreign_keys.name [FKName] 
        INTO FKAgainstTableList
        FROM sys.foreign_keys INNER JOIN sys.foreign_key_columns 
        ON sys.foreign_keys.object_id = sys.foreign_key_columns.constraint_object_id
        INNER JOIN sys.columns ON sys.columns.object_id = sys.foreign_keys.parent_object_id AND sys.columns.column_id = sys.foreign_key_columns.parent_column_id
        WHERE OBJECT_NAME(sys.foreign_keys.referenced_object_id) = @PKTableName
    
    
    DECLARE table_cur1 CURSOR  FOR
        SELECT  * FROM FKAgainstTableList
    
        PRINT @sql
    
    -------------------------------Disable constraint on FK Tables
    OPEN table_cur1
    FETCH NEXT FROM table_cur1 INTO @table,@FKColumnName,@FKName
    WHILE   @@FETCH_STATUS = 0
        BEGIN
            SET @sql ='ALTER TABLE '+@table+' DROP CONSTRAINT '+ @FKName
            PRINT @sql
            FETCH NEXT FROM table_cur1 INTO @table,@FKColumnName,@FKName
        END
    CLOSE table_cur1
    DEALLOCATE table_cur1
    --------------------------------DROP AND recreate CLUSTERED pk
    IF  EXISTS (SELECT 1 FROM sys.indexes WHERE object_id = OBJECT_ID(@PKTableName) AND name = @PKName)
    BEGIN
        SET @sql = 'ALTER TABLE '+@PKTableName+' DROP CONSTRAINT '+ @PKName
        PRINT @sql
    
    END
    SET @sql = 'ALTER TABLE '+@PKTableName +' ADD  CONSTRAINT '+@PKName+' PRIMARY KEY CLUSTERED ('+@PKcolumnName+' ASC)
    WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 80) ON [PRIMARY]'
    PRINT(@sql)
    
    --------------------------------Enable FK constraints on FK tables.
    DECLARE table_cur2 CURSOR  FOR
        SELECT  * FROM FKAgainstTableList
    OPEN table_cur2
    FETCH NEXT FROM table_cur2 INTO @table,@FKColumnName,@FKName
    WHILE   @@FETCH_STATUS = 0
        BEGIN
            SET @sql = 'ALTER TABLE '+@table+' WITH NOCHECK ADD  CONSTRAINT  '+ @FKName+' FOREIGN KEY(['+@FKColumnName+'])
            REFERENCES ['+@PKTableName+'] (['+@PKcolumnName+'])'
            PRINT(@sql)
            SET @sql = 'ALTER TABLE '+@table+' CHECK CONSTRAINT  '+@FKName
            PRINT(@sql)
    
            FETCH NEXT FROM table_cur2 INTO @table,@FKColumnName,@FKName
    
             END
    CLOSE table_cur2
    DEALLOCATE table_cur2
    DROP TABLE FKAgainstTableList
    

提交回复
热议问题