Как выполнить рефакторинг триггера, который использует вставленные и удаленные таблицы, чтобы переместить общий код в хранимую процедуру - PullRequest
2 голосов
/ 03 июня 2009

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

Триггер имеет длину около 90 строк, и единственная часть, которую мне действительно нужно отличать между триггерами:

DECLARE @DEBUG bit = 1
DECLARE @EntityName nvarchar(128) = 'Lot'
    SELECT * INTO #MYINSERTED FROM INSERTED
    SELECT * INTO #MYDELETED FROM DELETED

Если бы я мог перенести оставшуюся часть в хранимую процедуру, это было бы здорово.

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

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

Спасибо.

Ответы [ 2 ]

4 голосов
/ 03 июня 2009

Это на самом деле было бы плохой идеей. SQL не похож на ваш заурядный процедурный язык. SQL-компиляция связывается с физическим планом пути доступа, что означает, что операторы скомпилированы в планы, которые говорят «открытый набор строк с идентификатором 1234, поиск записи и получение ее содержимого», и что «1234» определяется во время составление пакета оптимизатором. Это означает, что перемещение общего кода в процедуру при планировании чаще наносит больший вред, чем приносит пользу. Процедура не может быть привязана к «общему» пути доступа, ей нужно знать фактические таблицы и объекты, на которые она должна обратить внимание при выборе, обновлении и тому подобном. Вы либо в конечном итоге выполняете динамический SQL в процедуре, либо перемещаете только не связанные с данными, общие части процедуры (например, вычисления), которые создают очень запутанный код и все же могут снизить производительность, в то же время уменьшая читаемость процедуры.

Гораздо более целесообразно иметь шаблон и генерировать триггеры из этого шаблона с помощью различных методов генерации кода, таких как XML и XSLT.

0 голосов
/ 03 июня 2009

Я подозреваю, что метаданные / схемы о inserted и deleted являются основной проблемой здесь (именно поэтому вы используете SELECT * INTO).

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

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

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

...