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

Я просмотрел несколько сообщений здесь о переполнении стека об ошибке 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 Ответ

0 голосов
/ 05 июня 2019

Чтобы обойти ошибку многокаскадного пути, вы можете создать триггер для проверки и удаления записи, как указано здесь .

Или вы можете создать отдельный столбец в качестве первичного ключа (может быть с автоматическим приращением 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
);

...