Sql 如果外键不存在,则在不使用名称的情况下添加外键约束(或删除外键约束,如果存在)?

Sql 如果外键不存在,则在不使用名称的情况下添加外键约束(或删除外键约束,如果存在)?,sql,sql-server-2008,Sql,Sql Server 2008,我发现创建查询很困难。假设我有一张产品和品牌表。我可以使用此命令添加外键 ALTER TABLE Products ADD FOREIGN KEY (BrandID) REFERENCES Brands(ID) 但我只需要在外键不存在时运行此命令。 我需要做的一件类似的事情是,如果存在外键约束而不使用名称,请删除该约束。尝试以下操作: IF NOT EXISTS (SELECT * FROM sys.objects o WHERE o

我发现创建查询很困难。假设我有一张产品和品牌表。我可以使用此命令添加外键

          ALTER TABLE Products
          ADD FOREIGN KEY (BrandID)
          REFERENCES Brands(ID)
但我只需要在外键不存在时运行此命令。 我需要做的一件类似的事情是,如果存在外键约束而不使用名称,请删除该约束。

尝试以下操作:

IF NOT EXISTS (SELECT * FROM sys.objects o WHERE o.object_id = object_id(N'[dbo].[FK_Products_Brands]') AND OBJECTPROPERTY(o.object_id, N'IsForeignKey') = 1)
BEGIN
    ALTER TABLE [dbo].[Products] WITH CHECK ADD CONSTRAINT [FK_Products_Brands] FOREIGN KEY([BrandID]) REFERENCES [dbo].[Brands] ([Id])
END

首先,您应该始终命名FK和所有其他约束,以避免这样的麻烦

但是,如果您不知道FK的名称,可以使用多个系统视图进行检查:

IF NOT EXISTS 
(
    SELECT * FROM sys.foreign_key_columns fk 
    INNER JOIN sys.columns pc ON pc.object_id = fk.parent_object_id AND pc.column_id = fk.parent_column_id 
    INNER JOIN sys.columns rc ON rc.object_id = fk.referenced_object_id AND rc.column_id = fk.referenced_column_id
    WHERE fk.parent_object_id = object_id('Products') AND pc.name = 'BrandID'
    AND fk.referenced_object_id = object_id('Brands') AND rc.NAME = 'ID'
)
ALTER TABLE Products 
ADD CONSTRAINT Your_New_FK_NAME FOREIGN KEY (BrandID)
REFERENCES Brands(ID)

你也可以用这个

IF(OBJECT_ID('FK_Products_Brands', 'F') IS NULL)
ALTER TABLE [dbo].[Products] WITH CHECK ADD CONSTRAINT [FK_Products_Brands] FOREIGN KEY([BrandID]) REFERENCES [dbo].[Brands] ([Id])

要在不知道约束名称和内部联接的情况下执行此操作,可以执行以下操作:

IF NOT EXISTS(SELECT NULL FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE WHERE [TABLE_NAME] = 'Products' AND [COLUMN_NAME] = 'BrandID')
BEGIN
    ALTER TABLE Products
    ADD FOREIGN KEY (BrandID)
    REFERENCES Brands(ID)
END

如果您愿意,您可以从该表中获取合同的名称,然后执行拖放操作。

我不知道fk_名称。你可以通过查看我上面的查询来更新它吗?你可以选择FK的名称,我选择了FK_Products_Brands作为示例。如果没有名称,这是不可能的吗?无论如何,谢谢。我认为为FKs制定命名约定是一个很好的做法;我不知道是否可以让sql server给它一个默认名称。如果不给它命名,sql会给它一些名称,比如
FK\uu Parent\u Table\uu Columns\uu 39E294A9
Good one。我只是想知道,我们是否可以使用相同的查询来检查是否存在外来查询,然后将其删除。请用这个更新你的答案。我会更新一下我的问题?@user960567好吧,为了删除密钥,你需要它的名称,所以它可能需要一些动态sql。谢谢,我现在也这么做了。但如果你把这个放在你的答案中,那么它将对未来的用户有所帮助。