Sha*_*mad 4 foreign-key sql-server metadata sql-server-2008-r2 alter-table
我在 SQL Server 2008 R2 机器上拥有系统管理员权限。我找到了一个脚本,它可以删除所有外键,并在测试导入后需要时为我们重新添加它们。因此,我执行以下代码时没有语法错误,因为它显示了“Alter Table [ParentTable] Drop Constraint FK_Name”...总共 23 个键,但是当我刷新服务器或数据库和表时,当我为每个表展开 Keys 节点时,我仍然看到它们吗?那么为什么不丢弃它们呢?另外,如果我想再次运行以进行测试,我是否需要将其转换为永久表或将脚本放入存储过程中?请指教。
我使用了“Pinal Dave”发布的“Swastik Mishra”中的以下脚本 http://blog.sqlauthority.com/2014/04/11/sql-server-drop-all-the-foreign-key-constraint-in- database-create-all-the-foreign-key-constraint-in-database/
SET NOCOUNT ON
DECLARE @table TABLE(
RowId INT PRIMARY KEY IDENTITY(1, 1),
ForeignKeyConstraintName NVARCHAR(200),
ForeignKeyConstraintTableSchema NVARCHAR(200),
ForeignKeyConstraintTableName NVARCHAR(200),
ForeignKeyConstraintColumnName NVARCHAR(200),
PrimaryKeyConstraintName NVARCHAR(200),
PrimaryKeyConstraintTableSchema NVARCHAR(200),
PrimaryKeyConstraintTableName NVARCHAR(200),
PrimaryKeyConstraintColumnName NVARCHAR(200)
)
INSERT INTO @table(ForeignKeyConstraintName, ForeignKeyConstraintTableSchema, ForeignKeyConstraintTableName, ForeignKeyConstraintColumnName)
SELECT
U.CONSTRAINT_NAME,
U.TABLE_SCHEMA,
U.TABLE_NAME,
U.COLUMN_NAME
FROM
INFORMATION_SCHEMA.KEY_COLUMN_USAGE U
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS C
ON U.CONSTRAINT_NAME = C.CONSTRAINT_NAME
WHERE
C.CONSTRAINT_TYPE = 'FOREIGN KEY'
UPDATE @table SET
PrimaryKeyConstraintName = UNIQUE_CONSTRAINT_NAME
FROM
@table T
INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS R
ON T.ForeignKeyConstraintName = R.CONSTRAINT_NAME
UPDATE @table SET
PrimaryKeyConstraintTableSchema = TABLE_SCHEMA,
PrimaryKeyConstraintTableName = TABLE_NAME
FROM @table T
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS C
ON T.PrimaryKeyConstraintName = C.CONSTRAINT_NAME
UPDATE @table SET
PrimaryKeyConstraintColumnName = COLUMN_NAME
FROM @table T
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE U
ON T.PrimaryKeyConstraintName = U.CONSTRAINT_NAME
--SELECT * FROM @table
--DROP CONSTRAINT:
SELECT
'
ALTER TABLE [' + ForeignKeyConstraintTableSchema + '].[' + ForeignKeyConstraintTableName + ']
DROP CONSTRAINT ' + ForeignKeyConstraintName + '
GO’
FROM
@table
–ADD CONSTRAINT:
SELECT
‘
ALTER TABLE [' + ForeignKeyConstraintTableSchema + '].[' + ForeignKeyConstraintTableName + ']
ADD CONSTRAINT ‘ + ForeignKeyConstraintName + ‘ FOREIGN KEY(‘ + ForeignKeyConstraintColumnName + ‘) REFERENCES [' + PrimaryKeyConstraintTableSchema + ']. [' + PrimaryKeyConstraintTableName + '](‘ + PrimaryKeyConstraintColumnName + ‘)
GO’
FROM
@table
GO
Run Code Online (Sandbox Code Playgroud)
Aar*_*and 16
这是一个更好的脚本。
INFORMATION_SCHEMA意见。除此之外,这些视图不会针对唯一约束公开外键;仅针对显式主键约束。GO放在 T-SQL 中,如果您动态执行命令,它将无法工作(因为它GO是 SSMS 等交互式工具的批处理分隔符,而不是 T-SQL 关键字)。’vs. ')。其余部分摘自我的博客文章,分组连接的四个实际用例。这是脚本#4。
下降很容易; 只需从 sys.foreign_keys 构建一个简单的 ALTER TABLE 命令列表(我还添加了注释掉的过滤器,可用于将范围限制为匹配命名模式或存在于某个模式中的引用表):
DECLARE @drop NVARCHAR(MAX) = N'';
SELECT @drop += N'
ALTER TABLE ' + QUOTENAME(cs.name) + '.' + QUOTENAME(ct.name)
+ ' DROP CONSTRAINT ' + QUOTENAME(fk.name) + ';'
FROM sys.foreign_keys AS fk
INNER JOIN sys.tables AS ct ON fk.parent_object_id = ct.[object_id]
INNER JOIN sys.schemas AS cs ON ct.[schema_id] = cs.[schema_id];
-- WHERE fk.referenced_object_id IN
-- (SELECT [object_id] FROM sys.tables WHERE name LIKE N'%some pattern%')
-- WHERE fk.referenced_schema_id IN
-- (SELECT [schema_id] FROM sys.schemas WHERE name = N'some_schema')
PRINT @drop;
Run Code Online (Sandbox Code Playgroud)
不要执行那个!当然,您需要在它们仍然存在时生成 CREATE 命令。创建有点复杂。我们需要生成约束两侧的列列表,即使在大多数情况下只有一列(多列情况是分组连接真正派上用场的地方):
DECLARE @create NVARCHAR(MAX) = N'';
SELECT @create += N'
ALTER TABLE '
+ QUOTENAME(cs.name) + '.' + QUOTENAME(ct.name)
+ ' ADD CONSTRAINT ' + QUOTENAME(fk.name)
+ ' FOREIGN KEY (' + STUFF((SELECT ',' + QUOTENAME(c.name)
FROM sys.columns AS c
INNER JOIN sys.foreign_key_columns AS fkc
ON fkc.parent_column_id = c.column_id
AND fkc.parent_object_id = c.[object_id]
WHERE fkc.constraint_object_id = fk.[object_id]
ORDER BY fkc.constraint_column_id
FOR XML PATH(N''), TYPE).value(N'.[1]', N'nvarchar(max)'), 1, 1, N'')
+ ') REFERENCES ' + QUOTENAME(rs.name) + '.' + QUOTENAME(rt.name)
+ '(' + STUFF((SELECT ',' + QUOTENAME(c.name)
FROM sys.columns AS c
INNER JOIN sys.foreign_key_columns AS fkc
ON fkc.referenced_column_id = c.column_id
AND fkc.referenced_object_id = c.[object_id]
WHERE fkc.constraint_object_id = fk.[object_id]
ORDER BY fkc.constraint_column_id
FOR XML PATH(N''), TYPE).value(N'.[1]', N'nvarchar(max)'), 1, 1, N'') + ');'
FROM sys.foreign_keys AS fk
INNER JOIN sys.tables AS rt -- referenced table
ON fk.referenced_object_id = rt.[object_id]
INNER JOIN sys.schemas AS rs ON rt.[schema_id] = rs.[schema_id]
INNER JOIN sys.tables AS ct -- constraint table
ON fk.parent_object_id = ct.[object_id]
INNER JOIN sys.schemas AS cs ON ct.[schema_id] = cs.[schema_id];
--WHERE rt.name LIKE N'%some pattern%'
--WHERE rs.name = N'some_schema'
PRINT @create;
Run Code Online (Sandbox Code Playgroud)
如果您对输出感到满意(请记住,PRINT 限制为 8K,因此该命令可能看起来像是被截断了),将其添加到末尾,然后再次运行:
EXEC sys.sp_executesql @drop;
-- drop and re-create the table here, whatever that needs to entail
EXEC sys.sp_executesql @create;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4759 次 |
| 最近记录: |