Доступ к полям из удаленных и вставленных таблиц в триггере - PullRequest
0 голосов
/ 31 октября 2018

У меня есть следующий триггер:

CREATE TRIGGER trFoodUpdate ON Food
AFTER UPDATE
AS
    DECLARE @Action nvarchar(1000) = 'Change(s): '

    IF Inserted.FoodID <> Deleted.FoodID THEN SET @Action += CHAR(13) + '-You have updated FoodID from ' + Inserted.FoodID + 'to ' + Deleted.FoodID
    .... --Other IF-s--


    INSERT INTO FoodTriggerTable (FoodID, FoodName, FoodDesc, FoodPrice, Action, InsertActionTime)
    SELECT FoodID, FoodName, FoodDesc, FoodPrice, @Action, GETDATE() FROM Inserted
GO

Я пытаюсь вставить обновленные FoodID, FoodName и т. Д. В мой FoodTriggerTable. Тем не менее, я не могу сделать:

IF Inserted.FoodID <> Deleted.FoodID THEN ...

В нем говорится, что «идентификатор из нескольких частей« Inserted.FoodID »не может быть связан». Такая же ошибка возникает на Deleted.FoodID. Почему это так?

Я подумал, что мог бы использовать DECLARE для объявления временных переменных, которые могут хранить все необходимые данные из указанных таблиц, но могу ли я использовать описанный выше подход?

EDIT

Кажется, я неправильно понял многие понятия в SQL Server, но я пытаюсь вставить обновленные FoodID, FoodName и остальные поля в таблицу с именем FoodTriggerTable, в которой хранятся «журналы», которые содержит информацию об обновлении записи.

Я пытаюсь вставить предложение, в котором перечислены изменения, внесенные в запись в моей таблице Food внутри моего FoodTriggerTable. Таким образом, я попытался установить новую переменную с именем @Action для хранения строки, которую я затем объединю с другими строками. Строка, содержащаяся в @Action, будет вставлена ​​в поле Action в FoodTriggerTable, используя:

INSERT INTO FoodTriggerTable (FoodID, FoodName, FoodDesc, FoodPrice, Action, InsertActionTime)
SELECT FoodID, FoodName, FoodDesc, FoodPrice, @Action, GETDATE() FROM Inserted

Предположим, я обновил только цену еды в таблице Food, я хотел бы, чтобы мое поле Action в FoodTriggerTable содержало следующую строку:

Change(s): You've changed the food price from 30 to 45

Итак, что я пытаюсь сделать, это объединить 'You've changed the food price from' + previous food price + 'to' + after update food price.

Ответы [ 2 ]

0 голосов
/ 31 октября 2018

Вот полный рабочий пример одного из способов решения подобных проблем. Он отслеживает изменения во всех столбцах. Я создал таблицы Food и FoodAudit в дополнение к триггеру выборки. Затем я создал несколько данных и обновил их несколько раз, чтобы вы могли увидеть, как это может работать.

create table Food
(
    FoodID int identity
    , FoodName varchar(100) not null
    , FoodDesc varchar(100) not null
    , FoodPrice decimal(7,2) not null
)

create table FoodAudit
(
    FoodID int not null
    , FoodName varchar(100) not null
    , FoodDesc varchar(100) not null
    , FoodPrice decimal(7,2) not null
    , ChangeDate datetime not null
        CONSTRAINT DF_FoodAudit_ChangeDate DEFAULT getdate()
)

GO

create trigger TR_Food on Food after UPDATE as

    set nocount on;

    insert FoodAudit
    (
        FoodID
        , FoodName
        , FoodDesc
        , FoodPrice
        , ChangeDate
    )
    select d.FoodID
        , d.FoodName
        , d.FoodDesc
        , d.FoodPrice
        , getdate()
    from deleted d

GO

insert Food
(
    FoodName
    , FoodDesc
    , FoodPrice
)
select 'Bacon'
    , 'Yummy'
    , 3.42

GO

update Food
set FoodPrice = 1.23
where FoodName = 'Bacon'

waitfor delay '00:00:02' --used to simulate updates at different times.

update Food
set FoodPrice = 12.23
    , FoodDesc = 'wow'
where FoodName = 'Bacon'

waitfor delay '00:00:02' --used to simulate updates at different times.

update Food
set FoodPrice = 12.23
    , FoodDesc = 'wait'
where FoodName = 'Bacon'

waitfor delay '00:00:02' --used to simulate updates at different times.

update Food
set FoodDesc = 'Yummers'
where FoodName = 'Bacon'

waitfor delay '00:00:02' --used to simulate updates at different times.

select * from FoodAudit
0 голосов
/ 31 октября 2018

Комментарии Шона уже указывают на основное недоразумение, подтвержденное вашим кодом.

Чтобы быть техническим и конкретным, причина, по которой вы получаете ошибку The multi-part identifier "Inserted.FoodID" could not be bound, заключается в том, что вы не включили Inserted или Deleted в предложение FROM.

Невозможно быть на 100% уверенным в своем неработающем коде, но, вероятно, вам нужно разобраться с тем, как вычислить столбец Action в вашем последнем запросе INSERT в вашем коде, используя выражение CASE, чтобы обрабатывать каждую строку в индивидуальном порядке.

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