SQL Server после запуска обновления
У меня проблема с этим триггером. Я хотел бы, чтобы он обновил запрашиваемую информацию
только к указанной строке (той, которую я только что обновил), а не всей таблице.
CREATE TRIGGER [dbo].[after_update]
ON [dbo].[MYTABLE]
AFTER UPDATE
AS
BEGIN
UPDATE MYTABLE
SET mytable.CHANGED_ON = GETDATE(),
CHANGED_BY=USER_NAME(USER_ID())
Как сообщить триггер, что это относится только к указанной строке?
Ответы
Ответ 1
Вот мой пример после теста
CREATE TRIGGER [dbo].UpdateTasadoresName
ON [dbo].Tasadores
FOR UPDATE
AS
UPDATE Tasadores
SET NombreCompleto = RTRIM( Tasadores.Nombre + ' ' + isnull(Tasadores.ApellidoPaterno,'') + ' ' + isnull(Tasadores.ApellidoMaterno,'') )
FROM Tasadores
INNER JOIN INSERTED i ON Tasadores.id = i.id
Введенная специальная таблица будет содержать информацию из обновленной записи.
Ответ 2
Попробуйте это (обновление, а не после обновления)
CREATE TRIGGER [dbo].[xxx_update] ON [dbo].[MYTABLE]
FOR UPDATE
AS
BEGIN
UPDATE MYTABLE
SET mytable.CHANGED_ON = GETDATE()
,CHANGED_BY = USER_NAME(USER_ID())
FROM inserted
WHERE MYTABLE.ID = inserted.ID
END
Ответ 3
Это очень просто сделать,
Сначала создайте копию своей таблицы, в которой хотите сохранить журнал для
Например, у вас есть таблица dbo.SalesOrder с столбцами SalesOrderId, FirstName, LastName, LastModified
Ваша архивная таблица версий должна быть dbo.SalesOrderVersionArchieve с столбцами SalesOrderVersionArhieveId, SalesOrderId, FirstName, LastName, LastModified
Вот как настроить триггер в таблице SalesOrder
USE [YOURDB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Karan Dhanu
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
CREATE TRIGGER dbo.[CreateVersionArchiveRow]
ON dbo.[SalesOrder]
AFTER Update
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO dbo.SalesOrderVersionArchive
SELECT *
FROM deleted;
END
Теперь, если вы внесете какие-либо изменения в таблицу saleOrder, вы увидите изменение в таблице VersionArchieve
Ответ 4
Вы должны иметь доступ к таблице INSERTED
и получить первичный ключ ID или таблицы. Что-то похожее на этот пример...
CREATE TRIGGER [dbo].[after_update] ON [dbo].[MYTABLE]
AFTER UPDATE AS
BEGIN
DECLARE @id AS INT
SELECT @id = [IdColumnName]
FROM INSERTED
UPDATE MYTABLE
SET mytable.CHANGED_ON = GETDATE(),
CHANGED_BY=USER_NAME(USER_ID())
WHERE [IdColumnName] = @id
Здесь ссылка на MSDN в таблицах INSERTED
и DELETED
, доступных при использовании триггеров: http://msdn.microsoft.com/en-au/library/ms191300.aspx
Ответ 5
попробуйте это решение.
DECLARE @Id INT
DECLARE @field VARCHAR(50)
SELECT @Id= INSERTED.CustomerId
FROM INSERTED
IF UPDATE(Name)
BEGIN
SET @field = 'Updated Name'
END
IF UPDATE(Country)
BEGIN
SET @field = 'Updated Country'
END
INSERT INTO CustomerLogs
VALUES(@Id, @field)
Я не проверял это со старой версией sql-сервера, но это будет работать с SQL-сервером 2012 года.
Ответ 6
Во-первых, ваш триггер, как вы уже видите, будет обновлять каждую запись в таблице. Фильтрация не выполняется, чтобы выполнить изменение строк.
Во-вторых, вы предполагаете, что только одна строка изменяется в партии, которая неверна, поскольку несколько строк могут меняться.
Для этого нужно использовать виртуальные вставленные и удаленные таблицы: http://msdn.microsoft.com/en-us/library/ms191300.aspx
Ответ 7
Попробуйте этот скрипт, чтобы создать временную таблицу TESTTEST и наблюдать порядок старшинства при вызове триггеров в следующем порядке: 1) INSTEAD OF, 2) FOR, 3) AFTER
Вся логика помещена в триггер INSTEAD OF, и у меня есть 2 примера того, как вы можете кодировать некоторые сценарии...
Удачи...
CREATE TABLE TESTTEST
(
ID INT,
Modified0 DATETIME,
Modified1 DATETIME
)
GO
CREATE TRIGGER [dbo].[tr_TESTTEST_0] ON [dbo].TESTTEST
INSTEAD OF INSERT,UPDATE,DELETE
AS
BEGIN
SELECT 'INSTEAD OF'
SELECT 'TT0.0'
SELECT * FROM TESTTEST
SELECT *, 'I' Mode
INTO #work
FROM INSERTED
UPDATE #work SET Mode='U' WHERE ID IN (SELECT ID FROM DELETED)
INSERT INTO #work (ID, Modified0, Modified1, Mode)
SELECT ID, Modified0, Modified1, 'D'
FROM DELETED WHERE ID NOT IN (SELECT ID FROM INSERTED)
--Check Security or any other logic to add and remove from #work before processing
DELETE FROM #work WHERE ID=9 -- because you don't want anyone to edit this id?!?!
DELETE FROM #work WHERE Mode='D' -- because you don't want anyone to delete any records
SELECT 'EV'
SELECT * FROM #work
IF(EXISTS(SELECT TOP 1 * FROM #work WHERE Mode='I'))
BEGIN
SELECT 'I0.0'
INSERT INTO dbo.TESTTEST (ID, Modified0, Modified1)
SELECT ID, Modified0, Modified1
FROM #work
WHERE Mode='I'
SELECT 'Cool stuff would happen here if you had FOR INSERT or AFTER INSERT triggers.'
SELECT 'I0.1'
END
IF(EXISTS(SELECT TOP 1 * FROM #work WHERE Mode='D'))
BEGIN
SELECT 'D0.0'
DELETE FROM TESTTEST WHERE ID IN (SELECT ID FROM #work WHERE Mode='D')
SELECT 'Cool stuff would happen here if you had FOR DELETE or AFTER DELETE triggers.'
SELECT 'D0.1'
END
IF(EXISTS(SELECT TOP 1 * FROM #work WHERE Mode='U'))
BEGIN
SELECT 'U0.0'
UPDATE t SET t.Modified0=e.Modified0, t.Modified1=e.Modified1
FROM dbo.TESTTEST t
INNER JOIN #work e ON e.ID = t.ID
WHERE e.Mode='U'
SELECT 'U0.1'
END
DROP TABLE #work
SELECT 'TT0.1'
SELECT * FROM TESTTEST
END
GO
CREATE TRIGGER [dbo].[tr_TESTTEST_1] ON [dbo].TESTTEST
FOR UPDATE
AS
BEGIN
SELECT 'FOR UPDATE'
SELECT 'TT1.0'
SELECT * FROM TESTTEST
SELECT 'I1'
SELECT * FROM INSERTED
SELECT 'D1'
SELECT * FROM DELETED
SELECT 'TT1.1'
SELECT * FROM TESTTEST
END
GO
CREATE TRIGGER [dbo].[tr_TESTTEST_2] ON [dbo].TESTTEST
AFTER UPDATE
AS
BEGIN
SELECT 'AFTER UPDATE'
SELECT 'TT2.0'
SELECT * FROM TESTTEST
SELECT 'I2'
SELECT * FROM INSERTED
SELECT 'D2'
SELECT * FROM DELETED
SELECT 'TT2.1'
SELECT * FROM TESTTEST
END
GO
SELECT 'Start'
INSERT INTO TESTTEST (ID, Modified0) VALUES (9, GETDATE())-- not going to insert
SELECT 'RESTART'
INSERT INTO TESTTEST (ID, Modified0) VALUES (10, GETDATE())--going to insert
SELECT 'RESTART'
UPDATE TESTTEST SET Modified1=GETDATE() WHERE ID=10-- gointo to update
SELECT 'RESTART'
DELETE FROM TESTTEST WHERE ID=10-- not going to DELETE
SELECT 'FINISHED'
SELECT * FROM TESTTEST
DROP TABLE TESTTEST
Ответ 8
CREATE TRIGGER [dbo].[after_update] ON [dbo].[MYTABLE]
AFTER UPDATE
AS
BEGIN
DECLARE @ID INT
SELECT @ID = D.ID
FROM inserted D
UPDATE MYTABLE
SET mytable.CHANGED_ON = GETDATE()
,CHANGED_BY = USER_NAME(USER_ID())
WHERE ID = @ID
END