У меня есть три таблицы в SQL Server 2014.
- Первая - это
Product
таблица (productid, ...) - Вторая содержит
ProductVersions
этогоproduct (ProductVersionID, ProductID, ...) - Третий содержит лицензии на продукты (LicenseID, ProductID)
Эти таблицы имеют внешние ключи для идентификатора продукта с каскадом удаления,
Теперь я хочу добавить еще одну таблицу, отображающую лицензии на конкретные ProductVersions
.Это может быть отношение: m, поэтому я создаю таблицу сопоставления LicenseVersion
(LicenseID, ProductVersionID
)
Когда я пытаюсь добавить внешний ключ к этим отношениям, я получаю сообщение об ошибке, в котором не может быть добавлен внешний ключпотому что есть петли или несколько каскадных путей.Используйте для удаления никаких действий или изменить внешний ключ.
Я думаю, я понимаю, почему это происходит (удаление продукта приведет к удалению строки LicenseVersion
в обоих направлениях за одну транзакцию), но как лучше всего решить эту проблему?
База данных должна быть согласованной в любое время, поэтому я не хочу решать это в логике программного приложения.
Я мог бы использовать триггер (я думаю) и внешний ключ без каких-либо действий, но лучше ли это?

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]