Как я могу редактировать значения INSERT в триггере на SQL Server? - PullRequest
28 голосов
/ 27 августа 2010

У меня есть таблица Tb

ID | Name   | Desc
-------------------------
 1 | Sample | sample desc

Я хочу создать триггер на INSERT, который изменит значение вставки Desc, например:

INSERT INTO Tb(Name, Desc) VALUES ('x', 'y')

Приведет к

ID | Name   | Desc
-------------------------
 1 | Sample | sample desc
 2 | x      | Y edited

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

Это то, что мне нужнополучите Desc, который вставляется, и измените его.

Как я могу это сделать?

Лучше ли обрабатывать его после вставки с обновлением?Или сделать триггер с помощью INSTEAD OF INSERT и изменять его каждый раз, когда изменяется структура таблицы?

Ответы [ 4 ]

37 голосов
/ 27 августа 2010

Использовать триггер после вставки. Присоединитесь из псевдотаблицы inserted к Tb по первичному ключу. Затем обновите значения desc. Что-то вроде: (но может не скомпилироваться)

CREATE TRIGGER TbFixTb_Trg 
ON  Tb  
AFTER INSERT 
AS  
BEGIN 
    UPDATE Tb
    SET DESC = SomeTransformationOf(i.DESC)
    FROM Tb
    INNER JOIN inserted i on i.Id = Tb.Id
END  
GO

Этот триггер происходит после вставки, но до завершения оператора insert. Таким образом, новые, неправильные значения уже помещены в целевую таблицу. Этот триггер не нужно будет изменять при добавлении, удалении столбцов и т. Д.

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

26 голосов
/ 27 августа 2010

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

То, что вы хотите, называется триггером INSTEAD OF INSERT, он запускается вместо вставки в таблицу с той логикой, которую вы ему даете.

CREATE TRIGGER trgUpdateDesc
ON  Tb 
INSTEAD OF INSERT
AS 
BEGIN
    SET NOCOUNT ON;
    INSERT INTO Tb (Name, [Desc])
    SELECT Name, [Desc] + 'edited'
    FROM inserted
END 
GO

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

О, также убедитесь, что поставьте [] вокруг Desc, так как это ключевое слово в sql server (обозначает нисходящий)

Надеюсь, это поможет!

Edit:

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

CREATE TRIGGER [dbo].[trgUpdateDesc]
   ON  [dbo].[Tb] 
   AFTER INSERT
AS 
BEGIN
    SET NOCOUNT ON;
    UPDATE Tb
    SET [Desc] = UPPER(inserted.[Desc]) +  ' Edited'
    FROM inserted INNER JOIN Tb On inserted.id = Tb.id
END 
9 голосов
/ 30 июня 2014

Временная таблица может помочь использовать INSTEAD OF INSERT триггер, избегая при этом явного перечисления всех несвязанных столбцов таблицы:

CREATE TRIGGER trgUpdateDesc
    ON Tb 
    INSTEAD OF INSERT
AS 
BEGIN
    SET NOCOUNT ON;
    select * into #tmp from inserted;
    UPDATE #tmp SET Desc = Desc + 'edited' --where ...;
    insert into Tb select * from #tmp;
    drop table #tmp;
END 

Этот код не нужно будет исправлять при добавлении новых столбцов в таблицу.

Но остерегайтесь некоторых дополнительных затрат на временные таблицы .

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

4 голосов
/ 27 августа 2010

Возможно, вы захотите взглянуть на INSTEAD OF триггеры.

CREATE TRIGGER Tb_InsteadTrigger on Tb
INSTEAD OF INSERT
AS
BEGIN
...

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

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