我有一个大型数据库,每个表都有uniqueidentifier
聚簇主键。我想从主键中删除聚簇索引,并将其放在每个表的标识列中。
当我想删除聚簇索引时,主键也将被删除。所以我必须再次创建主键。我写的脚本不起作用。请帮帮我
------------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
答案 0 :(得分:0)
主要问题是虽然主键既是约束又是索引,但它是通过约束创建的索引。这意味着,您只能通过CONSTRAINT
创建和删除。删除约束后,索引将消失。因此,请移除SET @sql2
和EXEC (@sql2);
。
请记住,如果您定义了任何引用任何这些主键的外键,则必须首先删除这些主键,然后在此特定操作完成后重新创建。
您还可以通过同时分配@column
和@indexname
个变量来节省一些查询复杂性:
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;