Внешний ключ SQL Server с несколькими каскадными путями - PullRequest
0 голосов
/ 24 сентября 2018

У меня есть три таблицы в SQL Server 2014.

  • Первая - это Product таблица (productid, ...)
  • Вторая содержит ProductVersions этогоproduct (ProductVersionID, ProductID, ...)
  • Третий содержит лицензии на продукты (LicenseID, ProductID)

Эти таблицы имеют внешние ключи для идентификатора продукта с каскадом удаления,

Теперь я хочу добавить еще одну таблицу, отображающую лицензии на конкретные ProductVersions.Это может быть отношение: m, поэтому я создаю таблицу сопоставления LicenseVersion (LicenseID, 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]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...