Принудительная вставка записи во вторичную таблицу каждый раз, когда запись вставляется в первичную таблицу

#sql #sql-server #tsql #parent-child #sql-insert

#sql #sql-сервер #tsql #родитель-потомок #sql-вставка

Вопрос:

В настройке SQL Server 2008 R2 у меня есть table1 (id, col1-1, col1-2, ...) и table2 (id, table1_id, col2-1, col2-2, ...) , где table2.table1_id указывает на table1.id (т. Е. Отношение внешнего ключа к первичному ключу).

Как мне обеспечить соблюдение правила, согласно которому каждый раз, когда кто-то вставляет запись table1 , он также должен создавать запись table2 ?

Я бы предположил, что очевидным механизмом для использования здесь являются триггеры, но это может привести к проблеме с курицей и яйцом, поскольку триггеру потребуется запись table2 in для создания записи in table1 , но для создания записи in table2 сначала мне нужно table1.id , чтобы значение уже существовало. Как это преодолеть?

Мне нужно, чтобы принудительное выполнение было автоматическим и встроенным в базу данных. Часто выполняемое задание для проверки наличия записей table1 без соответствующих записей table2 не приведет к сокращению, и правило должно применяться в режиме реального времени, когда кто-то фактически создает запись table1 .

Комментарии:

1. Хотя это и не «автоматическая и встроенная», если вы предоставляете хранимую процедуру для реализации AddMultitableStuff , предоставляете ей доступ на запись к таблицам и запрещаете пользователям доступ на запись к таблицам, вы можете управлять добавлением строк с помощью произвольных бизнес-правил.

Ответ №1:

Для этого можно просто использовать предложение OUTPUT . Вот простой пример

 CREATE TABLE Parent(Id INT, Col VARCHAR(45));
CREATE TABLE Child(Id INT, Col VARCHAR(45));

INSERT INTO Parent(Id, Col)
OUTPUT INSERTED.Id, INSERTED.Col INTO Child
VALUES(1, 'SomeValue');
  
SELECT *
FROM Parent P
JOIN Child C ON P.Id = C.Id;
  

Обратите внимание, что расширенная поддержка SQL Server 2008/2008 R2 заканчивается 9 июля 2019 года. Вам следует выполнить обновление как можно скорее.

Ответ №2:

Проблему с курицей и яйцом можно предотвратить, но я тестировал на Windows SQL 2016:

     CREATE TRIGGER [dbo].[Table1_Insert]
       ON [dbo].[Table1RR] AFTER INSERT
    AS
    IF rowcount_big() = 0 RETURN --leave trigger if no record (-s) inserted in the Table1
    SET NOCOUNT ON
    ALTER TABLE dbo.Table2RR NOCHECK CONSTRAINT FK_Table2_Table1 -- resolve chicken and the egg problem 
    INSERT INTO dbo.Table2RR select id,null,null from inserted order by id
    ALTER TABLE dbo.Table2RR CHECK CONSTRAINT FK_Table2_Table1
    GO
    ALTER TABLE [dbo].[Table1RR] ENABLE TRIGGER [Table1_Insert]
    GO