У меня есть таблица 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 и изменять его при каждом изменении структуры таблицы?
Используйте триггер после вставки. Соедините псевдотаблицу 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. Потому что это приведет к сбою оператора до того, как триггер сможет что-то исправить. (Пожалуйста, дважды проверьте этот абзац, прежде чем полагаться на него. Я давно не писал триггер.)
Я не уверен, где вы собираетесь получить фактическое новое значение для 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
Возможно, вы захотите взглянуть на триггеры INSTEAD OF
.
CREATE TRIGGER Tb_InsteadTrigger on Tb
INSTEAD OF INSERT
AS
BEGIN
...
Это позволит вам манипулировать данными до того, как они попадут в таблицу. Триггер отвечает за вставку данных в таблицу.