具有多个级联路径的SQL Server外键

时间:2018-09-24 18:38:06

标签: sql-server foreign-keys

我在SQL Server 2014中有三个表。

  • 第一个是Product表(productid,...)
  • 第二个包含该产品的ProductVersions(ProductVersionID,ProductID等)
  • 第三项包含产品的许可证(LicenseID,ProductID)

这些表在产品ID上带有外键,在删除级联时也是如此。

现在,我想添加另一个将许可证映射到特定ProductVersions的表。这可能是n:m关系,所以我创建了一个映射表LicenseVersionLicenseID, ProductVersionID

当我尝试向该关系添加外键时,我收到一条错误消息,因为存在循环或服务器级联路径,因此无法添加外键。用于删除任何操作或更改外键。

我想,为什么会发生这种情况(删除产品会导致LicenseVersion行在一次事务中同时从两种方式中删除),但是解决此问题的最佳实践是什么?

数据库应该随时保持一致,因此我不想在软件应用程序逻辑中解决此问题。

我可以使用触发器(我认为)和外键而不执行任何操作,但这是最好的方法吗?

database diagram

CREATE TABLE [dbo].[Products]
(
   [ProductID] [int] IDENTITY(1,1) NOT NULL,
   [ProductName] [nvarchar](255) NOT NULL,

   CONSTRAINT [PK_dbo.Products] 
       PRIMARY KEY CLUSTERED([ProductID] ASC)
)

CREATE TABLE [dbo].[ProductVersions]
(
   [ProductVersionID] [int] IDENTITY(1,1) NOT NULL,
   [ProductID] [int] NOT NULL,
   [Name] [nvarchar](255) NOT NULL,

   CONSTRAINT [PK_dbo.ProductVersions] 
       PRIMARY KEY CLUSTERED ([ProductVersionID] ASC)
) 

CREATE TABLE [dbo].[License]
(
   [LicenseId] [int] IDENTITY(1,1) NOT NULL,
   [LicenseName] [nvarchar](255) NOT NULL,
   [ProductId] [int] NOT NULL,

   CONSTRAINT [PK_dbo.License] 
       PRIMARY KEY CLUSTERED ([LicenseId] ASC)
)

CREATE NONCLUSTERED INDEX [IX_ProductId] 
     ON [dbo].[License] ([ProductId] ASC)

CREATE NONCLUSTERED INDEX [IX_ProductID] 
     ON [dbo].[ProductVersions] ([ProductID] ASC)

ALTER TABLE [dbo].[License] WITH CHECK 
    ADD CONSTRAINT [FK_dbo.License_dbo.Products_ProductId] 
        FOREIGN KEY([ProductId]) REFERENCES [dbo].[Products] ([ProductID])
                ON UPDATE CASCADE
                ON DELETE CASCADE

ALTER TABLE [dbo].[License] CHECK CONSTRAINT     [FK_dbo.License_dbo.Products_ProductId]

ALTER TABLE [dbo].[ProductVersions]  WITH CHECK 
    ADD CONSTRAINT [FK_dbo.ProductVersions_dbo.Products_ProductID] 
        FOREIGN KEY([ProductID]) REFERENCES [dbo].[Products] ([ProductID])
                ON UPDATE CASCADE
                ON DELETE CASCADE

ALTER TABLE [dbo].[ProductVersions] CHECK CONSTRAINT     [FK_dbo.ProductVersions_dbo.Products_ProductID]


--add new table
CREATE TABLE [dbo].[LicenseVersion]
(
   [LicenseID] [int] NOT NULL,
   [ProductVersionID] [int] NOT NULL,

   CONSTRAINT [PK_LicenseVersion] 
       PRIMARY KEY CLUSTERED ([LicenseID] ASC, [ProductVersionID] ASC)
) 

ALTER TABLE [dbo].[LicenseVersion] WITH CHECK 
    ADD CONSTRAINT [FK_LicenseVersion_ProductVersions] 
        FOREIGN KEY([ProductVersionID]) REFERENCES [dbo].[ProductVersions] ([ProductVersionID])
                ON UPDATE CASCADE
                ON DELETE CASCADE

ALTER TABLE [dbo].[LicenseVersion] CHECK CONSTRAINT     [FK_LicenseVersion_ProductVersions]

--error here:
ALTER TABLE [dbo].[LicenseVersion]  WITH CHECK 
    ADD CONSTRAINT [FK_LicenseVersion_Licenses] 
        FOREIGN KEY([LicenseID]) REFERENCES [dbo].[License] ([LicenseID])
                ON UPDATE CASCADE
                ON DELETE CASCADE

ALTER TABLE [dbo].[LicenseVersion] CHECK CONSTRAINT [FK_LicenseVersion_Licenses]

0 个答案:

没有答案