2015-12-17 2 views
0

Не уверен, что это было задано до причины при вводе текста заголовка, возможное дублирующее данное предложение не соответствует.Можем ли мы заменить триггер DML на хранимую процедуру

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

Я имею в виду сказать, например: AFTER INSERT Trigger имени trg_insert1 определяется на tbl1 который не обновить некоторые данные в tbl2, как показано ниже (принято SQL Server Пример, но вопрос не является специфической для какой-либо БД)

create trigger trg_insert1 
after insert on tbl1 
foreach row 
begin 

update tbl2 set somedata = inserted.tbl1somedata 
where id = inserted.tbl1id; 

end 

сейчас этот триггер можно заменить на SP, как показано ниже (с использованием блока транзакций);

create procedure usp_insertupdate (@name varchar(10), @data varchar(200)) 
as 
begin 
begin try 
begin trans 

insert into tbl1(name, data) values(@name, @data); 

    update tbl2 set somedata = @data 
    where id = scope_identity(); 

commit trans 
end try 

begin catch 

if @@TRANCOUNT > 0 
rollback trans 
end catch 
end 

Что будет работать практически во всех случаях триггера DML, как после/до -> вставить/удалить/обновить. НО я действительно не мог ответить/объяснить

какая разница тогда?

Это хорошая практика?

Невозможно ли во всех случаях?

Я думаю об этом сложнее.

Пожалуйста, дайте мне знать, что вы думаете.

[Примечание: Не конкретные СУБД, связанные с вопросом, хотя]

+1

Это ** очень ** RDBMS. –

ответ

2

Я попытаюсь ответить в очень общем смысле (вы указали, что это не предназначено для конкретной реализации).

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

Но ...

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

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

Это имеет важное значение: триггеры лучше обеспечивают согласованность. Если кто-то в спешке удаляет запись в вашем живом, например, набрав:

Delete from tablex where uid="QWTY10311" 

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

Execute SP_TABLEX_LOG("DELETE","QWTY10311") 

Ваша БД будет просто потерять данные молча.

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

Прежде всего, они записываются по записи. Поэтому, если вы удаляете 1 миллион записей, запись будет выполняться для каждой операции. Удачи, вызывая соответствующую хранимую процедуру с 1 миллионом строк курсора в качестве параметра, ESPECIALLY, если вы хотите сделать это после ручной операции, как в моем примере выше.

Второе преимущество: триггеры имеют специальную область, в которой они могут ссылаться на значения до и после изменения для каждого поля. Итак, если вы увеличиваете таблицу цен на 10% и хотите зарегистрировать то, что было в предыдущем значении, и какой пользователь выполнил действие в какое время, у вас будут «старое значение», «новое значение», «пользователь» -id "и" timestamp "для любой операции, которую вы можете захотеть сделать. Опять же, выполнение этого путем вызова хранимой процедуры означает, что вам нужно сохранить значения, чтобы передать их в хранимую процедуру при ее запуске.

Так зачем же с SP обращаться в любом случае? (на этот вопрос, надеюсь, будет ваш вопрос о «наилучшем варианте использования»).

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

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

+0

Да и, конечно, DML может произойти не только с помощью кода приложения, но и с работы третьей стороны ETL (или) массовой вставки (или) SSIS и т. Д. ... в этом случае SP не будет иметь никакого смысла, поскольку вы не можете никоим образом не отображают действие запуска с помощью SP. Кстати, приятное объяснение. – Rahul

1

Да хранимые процедуры могут быть использованы для замены DML триггеры таким образом, и является ли это хорошая практика, или нет, зависит от ваших потребностей.

Главное отличие состоит в том, что триггер будет запускать свой код каждый раз, когда он запускается. В вашем примере, если пользователь делает ad-hoc INSERT до tbl1, срабатывает триггер, и tbl2 будет обновляться.

Хранимая процедура может использоваться только для обеспечения соблюдения этого правила, если не разрешены временные ВСТАВКИ.

+0

Да и односторонняя хранимая процедура выглядит хорошо, потому что триггеры также носят пугающий характер. – Rahul

Смежные вопросы