Хранимая процедура и триггер - PullRequest
2 голосов
/ 11 января 2011

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

UPDATE CopyTable SET
    id = s.id,
    -- many, many fields
FROM MainTable s WHERE s.id IN (SELECT [id] FROM INSERTED)
                 AND CopyTable.id = s.id;

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

CREATE PROCEDURE UpdateCopy AS
BEGIN
UPDATE CopyTable SET
    id = s.id,
    -- many, many fields
    FROM MainTable s WHERE s.id IN (SELECT [id] FROM INSERTED)
    AND CopyTable.id = s.id;
END

Результат - Неверное имя объекта INSERTED.Как я могу обойти это?

С уважением,

Ответы [ 3 ]

4 голосов
/ 11 января 2011

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

Это T-SQL, декларативный язык доступа к данным.Это не ваш заурядный процедурный язык программирования.Распространенное мнение, такое как «повторное использование кода», не применимо в SQL, и это только вызовет проблемы с производительностью.Оставьте код в триггере, где он принадлежит.Для упрощения повторного факторинга генерируйте триггеры с помощью некоторого инструмента генерации кода, чтобы вы могли легко реорганизовать триггеры.

2 голосов
/ 11 января 2011

Проблема в том, что INSERTED доступен только во время триггера

- Запустить изменения для создания списка идентификаторов

DECLARE @idStack VARCHAR(max)
SET @idStack=','
SELECT @idStack=@idStack+ltrim(str(id))+',' FROM INSERTED

- вызвать изменения, чтобы вызвать сохраненный процесс

EXEC updateCopy(@idStack)

- Процедура получения списка идентификаторов через запятую

CREATE PROCEDURE UpdateCopy(@IDLIST VARCHAR(max)) AS
BEGIN
UPDATE CopyTable SET
    id = s.id,
    -- many, many fields

    FROM MainTable s WHERE charindex(','+ltrim(str(s.id))+',',@idList) > 0
    AND CopyTable.id = s.id;
END

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

Только что набрал на лету, но должен работать ОК

0 голосов
/ 14 января 2011

Реальный вопрос - «Как передать массив GUID в хранимую процедуру?» или, более широко, «Как передать массив в хранимую процедуру?».

Вот ответы:

http://www.sommarskog.se/arrays-in-sql-2005.html

http://www.sommarskog.se/arrays-in-sql-2008.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...