2

这听起来像是一个疯狂的要求。我报告的数据库没有任何外键,每个主键都是一个身份列。这使得使用 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'

谢谢你的耐心

4

5 回答 5

6

另一种选择是两步过程:

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

    SELECT
      'ALTER TABLE ' + OBJECT_NAME(OBJECT_ID) + ' DROP CONSTRAINT ' + name
    FROM sys.indexes WHERE is_primary_key = 1
    
  2. 使用该结果集,将其复制并粘贴到新的查询窗口中,然后运行它 - 它将从您运行它的数据库中的所有表中删除所有主键约束

这样,您就可以避开光标,并获得要执行的语句列表,如果您不需要它,您仍然可以“按原样”使用、调整甚至完全丢弃它。

于 2010-02-25T21:46:23.117 回答
5

这样的事情怎么样?

-- 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
于 2010-02-25T21:30:34.330 回答
1

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

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

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

于 2010-02-25T22:23:47.747 回答
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'

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

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

于 2010-02-25T23:14:58.000 回答
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
于 2015-07-27T09:27:10.470 回答