Триггер или хранимая процедура

Мне нужно обновлять table1.field1 из table2.field2 каждый раз, когда в table2 появляется новая запись. Я создал триггер, который делает именно это:

CREATE [dbo].[insert_trg]
on [dbo].[TheCat99]
AFTER INSERT AS
BEGIN
Update therefore.dbo.thecat99
SET factura = (SELECT dbo.pedido.num_factura
                    From dbo.Pedido
                    Where  dbo.thecat99.pedido=dbo.pedido.num_pedido)
WHERE dbo.thecat99.pedido = ( SELECT dbo.pedido.num_pedido
                           FROM dbo.pedido
                           Where dbo.thecat99.pedido = dbo.pedido.Num_Pedido)
AND dbo.thecat99.factura is NULL
END

Триггер работает, но он еще не запущен. Я читал о том, как триггеры плохие и злые, но я не вижу, как я могу сделать это, используя хранимые процедуры. Является ли триггер хорошей идеей? Если нет, как я могу сделать то же самое с хранимой процедурой?

1 ответ

Решение

Триггеры не плохие и не злые. Они являются отличным инструментом (и для некоторых задач единственным инструментом), но требуют знания и осторожного использования, поскольку их не так просто написать, как кажется на первый взгляд.

Как правило, триггеры должны быть максимально легкими и эффективными. Это связано с тем, что SQL Server не будет возвращать управление тому, кто выполнил оператор, который сработал, до тех пор, пока триггер также не будет завершен.

Сказав это, ваш код обновления может быть написан так (это будет более эффективным и более читабельным):

UPDATE t
SET factura = p.num_factura
FROM therefore.dbo.thecat99 t
INNER JOIN  dbo.Pedido p ON t.pedido= p.num_pedido
WHERE t.factura IS NULL

Однако, так как вы не используете inserted таблица, это означает, что каждый раз, когда любая строка вставляется в TheCat99 все ряды, где pedido значение соответствует num_pedido в Pedido будет использоваться для обновления. Есть еще возможности для улучшения - использование inserted стол вместо thecat99 означает, что вы будете работать только с теми записями, которые были только что вставлены в thecat99 таблица, так что ваш код будет гораздо более эффективным:

UPDATE t
SET factura = p.num_factura
FROM inserted t
INNER JOIN  dbo.Pedido p ON t.pedido= p.num_pedido
WHERE t.factura IS NULL
Другие вопросы по тегам