2015-04-04 2 views
2

У меня есть таблица, у которой есть 3 столбца id (первичный ключ int), A (int) и B (int).Как использовать обновление столбца при обновлении другого столбца?

Мое требование заключается в обновлении B, когда все происходит обновление А.

Так что я использовал триггер, и я попытался следующие

create trigger deTrigger on [dbo].[de] 
for update 
As 
declare @aValue int; 
select @aValue=i.A from inserted i; 
update de set B [email protected] 
GO 

, но я не знаю, как использовать where условие в выше, поэтому, когда я обновляю A в одной записи, все строки B col обновляются.

Если есть альтернативный способ использования триггера, то и пожалуйста, предложите

+1

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

+0

@JamesZ, так какое решение? – SpringLearner

+0

Возможно, что-то вроде «update d set B = iA из вставленного i присоединяется к d на i.xxx = d.xxx и i.yyy = d.yyy», где столбцы xxx и yyy - это ключи, которые идентифицируют правильные строки –

ответ

2

Вам нужно что-то вроде этого:

CREATE TRIGGER deTrigger 
ON [dbo].[de] 
FOR UPDATE 
AS 
    UPDATE de 
    SET B = i.A 
    FROM Inserted i 
    INNER JOIN Deleted d ON i.ID = d.ID 
    WHERE i.ID = de.ID 
     AND i.A <> d.A 
GO 

В принципе, вам нужно присоединиться к столу Inserted псевдо (так как это может содержат несколько строк), и вам также необходимо присоединиться к псевдо-таблице Deleted. Сравнивая значение от Inserted и Deleted, вы можете получить те строки, которые имели обновление столбца A, так и с теми, вы можете установить значение B в вашей de таблицы

+0

Спасибо за ответ. Не могли бы вы объяснить, почему я должен использовать удаленные, и если я не буду использовать то, в чем проблема. Кроме того, это вызовет проблему, если я последую примеру @JamesZ, предложенному в комментариях – SpringLearner

+0

@SpringLearner: путем сравнения «Inserted» (значения * new * после «UPDATE') и« Deleted »(старые значения до' UPDATE') вы можете узнать, какие строки имели изменение в столбце 'A' .... Если вы этого не сделаете, вы можете обновить столбец' B' в случае, когда что-то еще в таблице было изменено, а не в столбце А конкретно –

+0

позвольте мне попробовать в соответствии с вашим ответом – SpringLearner

1

Стандартный триггер SQL Server является «после» вызывать. Это полезно для обновления журналов и других типов «после использования факта». Но вы хотите изменить входящий поток, прежде чем он даже попадет в таблицу.

Для этого вам нужен триггер «до».

Какого SQL Server не имеет ...

Не волнуйтесь, хотя, SQL Server делает иметь "вместо" спускового крючка. Первоначально предназначенный только для представлений, он также удобно был доступен для таблиц, возможно, разработчикам MS не нужно беспокоиться о реализации триггеров «до».

Вот пример. В таблице расписания есть поле datetime (SchedDate) и связанное целое поле (SchedHour), которое содержит только час поля datetime. Поэтому всякий раз, когда SchedDate изменяется, время должно быть записано в SchedHour.

create trigger T_Schedule_bu ON Schedule 
instead of update as begin 
    set NoCount On; 

    update s 
     set s.Field1 = i.Field1, 
      s.Field2 = i.Field2, 
      s.SchedDate = i.SchedDate, 
      s.SchedHour = 
       case when i.SchedDate <> s.SchedDate 
        then DatePart(hour, i.SchedDate) 
        else s.SchedHour 
       end 
    from Schedule s 
    join inserted i 
     on i.ID = s.ID 
end; 

Другие поля изменены безоговорочно; SchedHour изменяется, только если SchedDate также был изменен. Фактически, в этом конкретном примере, действительно не обязательно выполнять этот тест. Он просто показывает, как это будет сделано.

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

0

попробовать это code-

create trigger deTrigger 
on [dbo].[de] 
for update 
As 
    update de 
    set B = i.A 
    FROM INSERTED i 
    WHERE de.id in (SELECT i.ID 
     FROM inserted i) 
Смежные вопросы