I have a large database with uniqueidentifier
clustered primary key on every table of it. I want to remove clustered indexes from primary keys and put it on an identity column in every table.
When I want to remove clustered indexes, primary key will be removed too. So I have to create primary keys, again. the script I have wrote doesn't work. please help me
------------drop all clustered primary keys and add nonclustered primary keys-------
DECLARE @table NVARCHAR(512), @tablename NVARCHAR(512),
@sql NVARCHAR(MAX), @sql2 NVARCHAR(MAX), @sql3 NVARCHAR(MAX),
@column NVARCHAR(MAX);
SELECT name As 'Table'
INTO #Indexes
FROM sys.tables
WHERE name like 'webware%'
WHILE (SELECT COUNT(*) FROM #Indexes) > 0
BEGIN
SET @table = (SELECT TOP 1 [Table] FROM #Indexes)
SET @column = (SELECT c.name
FROM sys.tables t
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
INNER JOIN sys.indexes i ON i.object_id = t.object_id
INNER JOIN sys.index_columns ic ON ic.object_id = t.object_id
INNER JOIN sys.columns c ON c.object_id = t.object_id
AND ic.column_id = c.column_id
WHERE i.is_primary_key = 1
AND t.name = @table)
DECLARE @indexname NVARCHAR(512);
SET @indexname = (SELECT i.name
FROM sys.tables t
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
INNER JOIN sys.indexes i ON i.object_id = t.object_id
INNER JOIN sys.index_columns ic ON ic.object_id = t.object_id
INNER JOIN sys.columns c ON c.object_id = t.object_id
AND ic.column_id = c.column_id
WHERE i.is_primary_key = 1
AND t.name = @table)
SET @sql = 'ALTER TABLE ' + @table + ' DROP CONSTRAINT ' + @indexname
SET @sql2 = 'DROP INDEX ' + @indexname + ' ON ' + @table
SET @sql3 ='ALTER TABLE ' + @table + ' ADD CONSTRAINT ' + @indexname+ ' PRIMARY KEY NONCLUSTERED(' + @column +')'
EXEC (@sql);
EXEC (@sql2);
EXEC (@sql3);
DELETE FROM #Indexes WHERE [Table] = @table;
END
DROP TABLE #Indexes
The main problem is that while a primary key is both a constraint and an index, it is an index that is created via the constraint. Meaning, you create and drop via CONSTRAINT
only. Once you drop the constraint, the index will be gone. So, remove SET @sql2
and the EXEC (@sql2);
.
Please keep in mind that if you have any foreign keys defined that reference any of these primary keys, those will have to be dropped first and then re-created after this particular operation completes.
You can also save some query complexity by assigning both @column
and @indexname
variables at the same time:
SELECT @column = c.name,
@indexname = i.name
FROM sys.tables t
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
INNER JOIN sys.indexes i ON i.object_id = t.object_id
INNER JOIN sys.index_columns ic ON ic.object_id = t.object_id
INNER JOIN sys.columns c ON c.object_id = t.object_id
AND ic.column_id = c.column_id
WHERE i.is_primary_key = 1
AND t.name = @table;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.