这听起来像是一个疯狂的请求。我报告的数据库没有任何外键,每个主键都是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'
感谢您的耐心
答案 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)
另一个选择是两个步骤:
首先,从系统目录视图中选择必要的信息,并使用它们构建实际删除索引和约束所需的T-SQL语句:
SELECT
'ALTER TABLE ' + OBJECT_NAME(OBJECT_ID) + ' DROP CONSTRAINT ' + name
FROM sys.indexes WHERE is_primary_key = 1
使用该结果集,复制&将其粘贴到新的查询窗口中并运行它 - 它将删除您在
这样你就可以避开游标了,你得到一个要执行的语句列表,如果你不需要它,你仍然可以“按原样”使用,调整,甚至完全丢弃。
答案 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