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

Sql 删除并重新创建引用多列的外键,sql,tsql,foreign-keys,truncate,composite-key,Sql,Tsql,Foreign Keys,Truncate,Composite Key,我正在尝试使用生产服务器中的数据刷新开发服务器,但这不能通过直接还原来完成,因为开发环境包含我们需要保留的prod环境中不包含的对象。所以我要做的是截断需要刷新的表,然后插入数据。我已经为此创建了一个程序,它一直工作到我们找到外键为止 我继承的DB编写得不是很好,在大多数表中都有几个主键列。我正在研究这个问题,并将@peter szanto和@marc-2377提供的最佳解决方案合并到存储过程中,只要插入到#FKs的sys.foreign_key_列中有一个唯一的约束,该存储过程就非常有效。使用

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

我继承的DB编写得不是很好,在大多数表中都有几个主键列。我正在研究这个问题,并将@peter szanto和@marc-2377提供的最佳解决方案合并到存储过程中,只要插入到#FKs的sys.foreign_key_列中有一个唯一的约束,该存储过程就非常有效。使用脚本会导致错误

“引用的表中没有主键或候选键”

在某些表上,它们将引用具有多个主键列作为一个外键的表

代码按原样返回这些值,以便在表
FK\u stmnt

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\uuu 12345约束,将列合并到一个语句中


有什么想法吗?

以下SQL将列出所有FK、表名、FK键、引用的表和引用的键…如果有多个键,则为逗号分隔的列表

这只是我的股票工具包中的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;

以下SQL将列出所有FK、表名、FK键、引用的表和引用的键…如果有多个键,则为逗号分隔的列表

这只是我的股票工具包中的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;

要使一个表中有多个列与另一个表的多个列具有fk关系,此语法有效:

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

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

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

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

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

如果组合键(包括主键)满足业务需求,则它们是可以的。如果它们满足业务需求,则是可以的。但这实际上是一个到处都有重复数据的数据库的巨大噩梦,因此,如果组合键(包括主键)满足业务需求,那么几乎每个表上的组合键都是可以的。如果它们满足业务需求,那么是可以的。但这实际上是一个到处都有重复数据的数据库的巨大噩梦,因此几乎每个表上都有fk
和c.column\u id=fc的复合键。parent\u column\u id
这对我来说是失败的,因为fc。parent\u column\u id有时与parent中的列id不同:
T(u,obj);配对(u,o1,o2,fk1(u,o1)参考T(u,obj),fk2(u,o2)参考T(u,obj)
这里3列成对
引用
T
中的2列。我不确定我是否理解…一个FK如何将3列关联到2列?它不能。它们必须匹配。是的,它们可以有2个FK,请参见注释中的示例,这是合法sql。哦,我想我明白你的意思。我的版本中有一个复制粘贴错误。应该重新设置引用的列id。我将更新答案。这看起来很有用,但出于某种原因,开箱即用在ReferencedFKFolumns中随机返回大量空值。
和c.column\u id=fc.parent\u column\u id
这对我来说失败,因为fc.parent\u column\u id有时与parent中的列id不同:
T(u,obj);Pairs(u,o1,o2,fk1(u,o1)ref T(u,obj),fk2(u,o2)参考T(u,obj)
这里3列成对
引用
T
中的2列。我不确定我是否理解…一个FK如何将3列关联到2列?它不能。它们必须匹配。是的,它们可以有2个FK,请参见注释中的示例,这是合法sql。哦,我想我明白你的意思。我的版本中有一个复制粘贴错误。应该重新设置引用的列id。我将更新答案。这看起来很有用,但出于某种原因,out the box似乎会在ReferencedFKFolumns中随机返回大量空值。问题是如何获取表中已有的FK常量,而不是如何创建它们。谢谢问题是如何获取表中已有的FK常量,而不是如何创建它们。谢谢