Многокаскадный путь SQL Server решен с добавлением независимого первичного ключа
Я просмотрел несколько сообщений здесь о переполнении стека об ошибке SQL Server 1785: введение ограничения FOREIGN KEY может привести к циклам или множественным каскадным путям. И я обнаружил, что это функция продукта Microsoft - не проверять циклы, и общая рекомендация - обойти это с помощью триггеров.
Итак, мой вопрос был:
Как создать зависимости внешнего ключа от нескольких таблиц в SQL Server?
По ошибке я обнаружил, что если я создаю отдельный независимый PRIMARY KEY, я могу создать таблицу с несколькими каскадными путями без ошибок (и она работает функционально, как и ожидалось). Для справки я использую SQL Server 2019.
Следующее генерирует ошибку:
CREATE TABLE t1 (
id bigint,
CONSTRAINT PK_t1 PRIMARY KEY CLUSTERED (id)
);
CREATE TABLE t2 (
id bigint,
CONSTRAINT PK_t2 PRIMARY KEY CLUSTERED (id)
);
CREATE TABLE cross_t1_t2 (
t1_id bigint,
t2_id bigint,
CONSTRAINT PK_cross_t1_t2 PRIMARY KEY CLUSTERED (t1_id,t2_id),
CONSTRAINT FK_cross_t1_t2_t1 FOREIGN KEY (t1_id)
REFERENCES customers (id)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT FK_cross_t1_t2_t2 FOREIGN KEY (t2_id)
REFERENCES addresses (id)
ON DELETE CASCADE
ON UPDATE CASCADE
);
Поскольку я нигде не мог найти этот ответ, я публикую его здесь в качестве альтернативы обходного пути триггера. Было бы неплохо узнать, почему это происходит.
1 ответ
Чтобы обойти ошибку множественного каскадного пути, вы можете создать триггер для проверки и удаления записи, как упомянуто здесь.
Или вы можете создать отдельный столбец в качестве первичного ключа (может быть автоматическое увеличение IDENTITY
)
Следующее не генерирует ошибку:
CREATE TABLE t3 (
id bigint,
CONSTRAINT PK_t3 PRIMARY KEY CLUSTERED (id)
)
CREATE TABLE t4 (
id bigint,
CONSTRAINT PK_t4 PRIMARY KEY CLUSTERED (id)
);
CREATE TABLE cross_t3_t4 (
id bigint,-- THE ONLY DIFFERENCE IS THE CREATION OF A SEPARATE PK
t3_id bigint,
t4_id bigint,
--Constraints
CONSTRAINT PK_cross_t3_t4 PRIMARY KEY CLUSTERED (id),
CONSTRAINT FK_cross_t3_t4_t3 FOREIGN KEY (t3_id)
REFERENCES t3 (id)
ON DELETE CASCADE
ON UPDATE CASCADE,
CONSTRAINT FK_cross_t3_t4_t4 FOREIGN KEY (t4_id)
REFERENCES t4 (id)
ON DELETE CASCADE
ON UPDATE CASCADE
);