删除并重新创建引用多列的外键

Drop and recreate foreign key referencing multiple columns

我正在尝试使用来自生产服务器的数据刷新开发服务器,但这不能通过直接恢复来完成,因为开发环境包含我们需要保留的不在生产环境中的对象。所以我想做的是截断需要刷新的 tables 然后插入数据。我为此创建了一个程序,它一直有效,直到我们找到外键。

我继承的DB写得不是很好,在大多数table中都有几个主键列。我正在查看这个问题 Cannot truncate table because it is being referenced by a FOREIGN KEY constraint?,并将 @peter-szanto 和 @marc-2377 提供的最佳解决方案合并到存储过程中,只要 sys.foreign_key_columns 中有一个唯一约束,它就可以很好地工作插入#FKs。使用脚本导致错误

"There are no primary or candidate keys in the referenced table"

在一些 table 上,因为它们引用 table 具有多个主键列作为一个外键。

原样的代码 returns 这些用于在 table FK_stmnt

中重新创建 fks
ALTER TABLE [dbo].[sometable] WITH NOCHECK 
    ADD CONSTRAINT [sometable$othertable__12345] 
        FOREIGN KEY([fk1]) REFERENCES [dbo].[othertable] ([pk1])

ALTER TABLE [dbo].[sometable] WITH NOCHECK 
    ADD CONSTRAINT [sometable$othertable__12345] 
        FOREIGN KEY([fk2]) REFERENCES [dbo].[othertable] ([pk2])

ALTER TABLE [dbo].[sometable] WITH NOCHECK 
    ADD CONSTRAINT [sometable$othertable__12345] 
        FOREIGN KEY([fk3]) REFERENCES [dbo].[othertable] ([pk3])

ALTER TABLE [dbo].[sometable] WITH NOCHECK 
    ADD CONSTRAINT [sometable$othertable__12345] 
        FOREIGN KEY([fk4]) REFERENCES [dbo].[othertable] ([pk4])

ALTER TABLE [dbo].[sometable] WITH NOCHECK 
    ADD CONSTRAINT [sometable$othertable__12345] 
        FOREIGN KEY([fk5]) REFERENCES [dbo].[othertable] ([pk5])

需要返回结果

ALTER TABLE [dbo].[sometable] WITH NOCHECK 
    ADD CONSTRAINT [sometable$othertable__12345] 
        FOREIGN KEY ([fk1], [fk2], [fk3], [fk4], [fk5]) 
            REFERENCES [dbo].[othertable] ([pk1], [pk2], [pk3], [pk4], [pk5])

对于每个 sometable$othertable__12345 约束,将列组合在一个语句中。

有什么想法吗?

以下 SQL 将列出所有外键、table 名称、外键键、引用的 table 和引用的键……如果有不止一个键,它是一个逗号分隔的列表。

这只是 SQL 来自我的库存工具包,并不是真正针对您的具体问题量身定制的,但您应该能够根据您的使用情况对其进行调整以生成您需要的内容。

 SELECT fkeys.[name] AS FKName, 
        OBJECT_NAME(fkeys.parent_object_id) AS TableName,
        (SELECT STUFF((SELECT ',' + c.[name]
         FROM sys.foreign_keys fk INNER JOIN sys.tables t ON fk.parent_object_id = t.object_id
              INNER JOIN sys.columns as c ON t.object_id = c.object_id
              INNER JOIN sys.foreign_key_columns AS fc ON c.column_id = fc.parent_column_id 
                                                      AND fc.constraint_object_id = fk.object_id 
                                                      AND fc.parent_object_id = fk.parent_object_id 
        WHERE fk.[name] = fkeys.[name]
        FOR XML PATH ('')), 1, 1, '')) AS FKFolumns,
        OBJECT_NAME(fkeys.referenced_object_id) AS ReferencedTableName,
        (SELECT STUFF((SELECT ',' + c.[name]
         FROM sys.foreign_keys fk INNER JOIN sys.tables t ON fk.referenced_object_id = t.object_id
              INNER JOIN sys.columns as c ON t.object_id = c.object_id
              INNER JOIN sys.foreign_key_columns AS fc ON c.column_id = fc.referenced_column_id 
                                                      AND fc.constraint_object_id = fk.object_id 
                                                      AND fc.referenced_object_id = fk.referenced_object_id 
        WHERE fk.[name] = fkeys.[name]
        FOR XML PATH ('')), 1, 1, '')) AS ReferencedFKFolumns
   FROM sys.foreign_keys fkeys
  ORDER BY FKName;

要在一个 table 中有多个列与另一个 table 的多个列有 fk 关系,此语法有效:

alter table dbo.x
    add constraint FK_A foreign key ([SalesOrderID] ,[SalesOrderDetailID])
        references dbo.y1 ([SalesOrderID] , [SalesOrderDetailID])

在 table dbo.y1 中,两列是 dbo.y1 上的主键。