删除所有主键

时间:2010-02-25 21:23:38

标签: tsql sql-server-2000 constraints information-schema

这听起来像是一个疯狂的请求。我报告的数据库没有任何外键,每个主键都是identity_column。这使得使用诸如TOAD之类的工具变得困难,因为Intellisense通过读取PK和FK关系来工作。

任何人都有一个脚本可以从数据库中的每个表中删除主键,因此我可以用“正确的”PK替换它们并添加FK以帮助报告?

要避开“不要做!!!”的意思回复,让我明确表示我不会对我的生产数据库执行此操作,而是将其复制到另一台服务器上。

任何建议都将不胜感激。

-------编辑使用正确的信息进行更新。 ----------------

谢谢你们,但我意识到我犯了一个错误。几乎每个表都有一个具有身份属性的“identity_column”。该身份是聚集索引。但是,它未被指定为主键。

首先,主键和聚簇索引之间有什么区别?

其次,如何编写所有聚簇索引的脚本? 这会有用吗?

SELECT 
  'ALTER TABLE ' + OBJECT_NAME(OBJECT_ID) + ' DROP CONSTRAINT ' + name 
FROM sys.indexes WHERE type_desc = 'CLUSTERED'

感谢您的耐心

5 个答案:

答案 0 :(得分:5)

this之类的内容怎么办?

-- Helper Procedure 
CREATE PROC #DropConstraints 
  @tableSchema nvarchar(max), 
  @tableName nvarchar(max), 
  @constraintType nvarchar(20) 
AS 
BEGIN 
  DECLARE @cName nvarchar(max); 

  DECLARE constraint_cursor CURSOR FOR 
    SELECT CONSTRAINT_NAME  
    FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
    WHERE  
      CONSTRAINT_TYPE = @constraintType 
      AND TABLE_NAME = @tableName 
      AND TABLE_SCHEMA = @tableSchema 

  OPEN constraint_cursor 

  FETCH NEXT FROM constraint_cursor INTO @cName 
  WHILE @@FETCH_STATUS = 0 
  BEGIN 
    EXEC ('ALTER TABLE ' + @tableSchema + '.' + @tableName + ' DROP CONSTRAINT ' + @cName); 
    FETCH NEXT FROM constraint_cursor INTO @cName 
  END 

  CLOSE constraint_cursor 
  DEALLOCATE constraint_cursor 
END 
GO

BEGIN TRANSACTION

  -- Setup Cursor for looping 
  DECLARE table_cursor SCROLL CURSOR FOR 
    SELECT TABLE_SCHEMA, TABLE_NAME  
    FROM INFORMATION_SCHEMA.TABLES 

  OPEN table_cursor

  -- Declare Variables

  DECLARE 
    @tableSchema nvarchar(max), 
    @tableName nvarchar(max) 

 -- Drop Primary Keys 

  FETCH FIRST FROM table_cursor INTO @tableSchema, @tableName 
  WHILE @@FETCH_STATUS = 0 
  BEGIN 
    EXEC #DropConstraints @tableSchema, @tableName, 'PRIMARY KEY'; 

    FETCH NEXT FROM table_cursor INTO @tableSchema, @tableName 
  END 

  -- Cleanup 
  CLOSE table_cursor 
  DEALLOCATE table_cursor

COMMIT TRANSACTION 
GO

DROP PROCEDURE #DropConstraints;
GO

答案 1 :(得分:4)

另一个选择是两个步骤:

  1. 首先,从系统目录视图中选择必要的信息,并使用它们构建实际删除索引和约束所需的T-SQL语句:

    SELECT
      'ALTER TABLE ' + OBJECT_NAME(OBJECT_ID) + ' DROP CONSTRAINT ' + name
    FROM sys.indexes WHERE is_primary_key = 1
    
  2. 使用该结果集,复制&将其粘贴到新的查询窗口中并运行它 - 它将删除您在

  3. 中运行的数据库中所有表的所有主键约束

    这样你就可以避开游标了,你得到一个要执行的语句列表,如果你不需要它,你仍然可以“按原样”使用,调整,甚至完全丢弃。

答案 2 :(得分:1)

回答关于PK和聚集索引之间差异的问题:

主键是保证记录唯一标识的关键值。它们与聚簇索引(它们规定了记录物理存储的顺序)无关,除了创建主键的默认值是使其成为聚簇索引。但是,您不必将其设为聚簇索引。

请注意,如果过去没有主键和外键,您的数据可能会被彻底清除,在清理之前不应创建外键。

答案 3 :(得分:1)

要删除所有聚簇索引,必须区分约束(主要或唯一)是聚簇索引或非约束索引是聚簇索引的情况。您不能使用DROP INDEX删除约束索引,也不能使用DROP CONSTRAINT删除索引。所以你需要做类似的事情:

Select 'ALTER TABLE ' + QUOTENAME(OBJECT_NAME([object_id])) + ' DROP CONSTRAINT ' + QUOTENAME([name])
From sys.indexes
Where is_primary_key = 1 Or is_unique_constraint = 1
 And type_desc = 'CLUSTERED'
Union All
Select 'DROP INDEX ' + QUOTENAME([name]) + ' ON ' + QUOTENAME(OBJECT_NAME([object_id])) 
from sys.indexes
Where is_primary_key = 0 And is_unique_constraint = 0
 And type_desc = 'CLUSTERED'

坦率地说,即使这可能也行不通,因为在删除主键之前必须删除所有主键的所有外键。要做到这一点,您需要编写所有外键的脚本,将它们全部删除,然后删除所有聚簇约束,然后重新创建所有外键。

我不得不问这是否真的是你想要做的。通过删除所有聚簇索引,您将强制重建所有受影响的表中的所有索引。

答案 4 :(得分:0)

我之前提供的代码示例,既是主键版本,也是其他类型的聚簇索引。

但是,没有人会关注默认方案中对象可能不存在的事实,也没有控制索引和约束不是SQL Server需要的系统对象。

这是简单版本,只删除主键:

select  'ALTER TABLE ' + quotename(object_schema_name(object_id)) + '.'
        + quotename(object_name(object_id)) + ' DROP CONSTRAINT ' + name
from    sys.indexes
where   is_primary_key = 1

这是第二个版本,它还编写了删除非主键聚簇索引的脚本:

select  'ALTER TABLE ' + quotename(object_schema_name(object_id)) + '.'
        + quotename(object_name([object_id])) + ' DROP CONSTRAINT '
        + quotename([name])
from    sys.indexes
where   is_primary_key = 1
        or is_unique_constraint = 1
        and type_desc = 'CLUSTERED'
union all
select  'DROP INDEX ' + quotename(i.[name]) + ' ON '
        + quotename(object_schema_name(i.[object_id])) + '.'
        + +quotename(object_name(i.[object_id]))
from    sys.indexes as i
        inner join sys.objects as o on o.object_id = i.object_id
where   is_primary_key = 0
        and is_unique_constraint = 0
        and i.type_desc = 'CLUSTERED'
        and o.[type] not in ( 'S' )
        and o.is_ms_shipped = 0