Как я могу редактировать значения INSERT в триггере на SQL Server?

У меня есть таблица 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 изменил его на верхний регистр и добавил отредактированный в конце.

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

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

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

30
задан Vadzim 29 May 2015 в 07:16
поделиться

3 ответа

Используйте триггер после вставки. Соедините псевдотаблицу insert с 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. Таким образом, новые неверные значения уже помещены в целевую таблицу. Этот триггер не нужно будет изменять при добавлении, удалении столбцов и т. д.

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

38
ответ дан 27 November 2019 в 23:21
поделиться

Я не уверен, где вы собираетесь получить фактическое новое значение для 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 (обозначает нисходящий)

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

Редактировать:

Если вы хотите сделать его немного более надежным, чтобы он не так сильно зависел от структуры таблицы, вы можете использовать триггер 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 
26
ответ дан 27 November 2019 в 23:21
поделиться

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

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

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

4
ответ дан 27 November 2019 в 23:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: