2014-11-21 3 views
0

Ниже мой триггер на SQL Server 2008Trigger Сохранение неверной информации

ALTER TRIGGER [dbo].[Trigger_UpdateLeadMasters] ON [dbo].[LeadMasters] 
FOR UPDATE 
AS 

DECLARE @CompanyName nvarchar(50); 
DECLARE @PersonName nvarchar(50); 
DECLARE @Designation nvarchar(50); 
DECLARE @Number nvarchar(50); 
DECLARE @Number2 nvarchar(50); 
DECLARE @Emailaddress nvarchar(50); 
DECLARE @Address nvarchar(MAX); 
DECLARE @Address2 nvarchar(MAX); 
DECLARE @CityName nvarchar(50); 
DECLARE @State nvarchar(50); 
DECLARE @PinNumber nvarchar(50); 
DECLARE @Product nvarchar(50); 
DECLARE @RemarkNote nvarchar(MAX); 
DECLARE @Audit_Action varchar(100); 


select @CompanyName=i.CompanyName from inserted i; 
select @PersonName=i.PersonName from inserted i;   
select @Designation=i.Designation from inserted i; 
select @Number=i.Number from inserted i;   
select @Number2=i.Number2 from inserted i;  
select @EmailAddress=i.EmailAddress from inserted i;   
select @Address=i.Address from inserted i;  
select @Address2=i.Address2 from inserted i;  
select @CityName=i.CityName from inserted i;   
select @State=i.State from inserted i;  
select @PinNumber=i.PinNumber from inserted i; 
select @Product=i.Product from inserted i;  
select @RemarkNote=i.RemarkNote from inserted i; 

IF UPDATE(CompanyName) 
set @Audit_Action=' Name Modified or Updated' 
IF UPDATE(PersonName) 
set @Audit_Action='Person Name Modified or Updated' 
IF UPDATE(Designation) 
set @Audit_Action='Designation Modified or Updated' 
IF UPDATE(Number) 
set @Audit_Action='1st Phone Number Modified or Updated' 
IF UPDATE(Number2) 
set @Audit_Action='2nd Phone Number Modified or Updated' 
IF UPDATE(EmailAddress) 
set @Audit_Action='Email Address Modified or Updated' 
IF UPDATE(Address) 
set @Audit_Action='Address Modified or Updated' 
IF UPDATE(Address2) 
set @Audit_Action='Alternate Address Modified or Updated' 
IF UPDATE(CityName) 
set @Audit_Action='City Name Modified or Updated' 
IF UPDATE(State) 
set @Audit_Action='State Modified or Updated' 
IF UPDATE(PinNumber) 
set @Audit_Action='PinNumber Modified or Updated' 
IF UPDATE(Product) 
set @Audit_Action='Product Field Modified or Updated' 
IF UPDATE(RemarkNote) 
set @Audit_Action='Remark Note Modified or Updated' 

insert into LoggerLeadMasters(CompanyName,PersonName,Designation,Number,Number2,EmailAddress,Address,Address2,CityName,State,PinNumber,Product,RemarkNote,Audit_Action,Audit_Timestamp) 
Values(@CompanyName,@PersonName,@Designation,@Number,@Number2,@EmailAddress,@Address,@Address2,@CityName,@State,@PinNumber,@Product,@RemarkNote,@Audit_Action,GETDATE()) 

Но проблема в том, когда я могу изменить любое поле в LeadMasters таблице, триггер переходит в линию

IF UPDATE(RemarkNote) 
set @Audit_Action='Remark Note Modified or Updated' 

и магазины неправильно информация для LoggerLeadMasters.Can, кто-нибудь поможет мне исправить эту проблему

Thanks

+2

У вашего триггера есть ** ОСНОВНАЯ ** ошибка в том, что вы, кажется, считаете, что она будет называться ** один раз в строке ** - это ** не ** случай. Триггер будет срабатывать ** один раз за оператор **, поэтому, если ваши утверждения 'UPDATE' влияют на 25 строк, вы будете запускать триггер ** сразу **, но тогда' Inserted' и 'Deleted' будут содержать 25 строк , Какой из этих 25 строк будет выбран ваш код? 'select @ CompanyName = i.CompanyName из вставленного i;' - он не детерминирован - один будет выбран, остальные игнорируются. Для этого нужно переписать триггер! –

+0

Благодаря @marc_s вы можете предложить изменения в моем коде? – user2614235

+1

Помимо проблемы операции установки, измеренной marc_s, будет ли ожидаемое значение Audit_Action, если будет обновлено более одного поля, например. CityName и адрес и ...? – bummi

ответ

3

В принципе, вам нужно переработать триггер, чтобы иметь возможность обрабатывать несколько строк в таблице InsertedDeleted). Псевдо-таблица - ваш триггер вызывается только один раз, даже если оператор UPDATE влияет на 10, 20, 50 строк.

Так в основном, ваш код должен выглядеть следующим образом:

ALTER TRIGGER [dbo].[Trigger_UpdateLeadMasters] 
ON [dbo].[LeadMasters] 
FOR UPDATE 
AS 
    INSERT INTO dbo.LoggerLeadMasters(CompanyName, PersonName, Designation, Number, Number2, 
             EmailAddress, Address, Address2, CityName, State, 
             PinNumber, Product, RemarkNote, 
             Audit_Action, Audit_Timestamp) 
     SELECT 
      CompanyName, PersonName, Designation, Number, Number2, 
      EmailAddress, Address, Address2, CityName, State, 
      PinNumber, Product, RemarkNote, 
      '?????', GETDATE() 
     FROM 
      Inserted 

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

Как правило, вы не можете просто преобразовать это в одну строку - то, что обычно делается для хранения старых и новых столбцов, представляющих интерес, и, следовательно, вы всегда имеете информацию о том, что было обновлено позже.

также: SQL Server и новее есть много этой функциональности уже встроенной - это называется Change Data Capture и это потенциально может спасти вас от необходимости писать десятки триггеров - проверить это!

+0

marc_c Спасибо за ответ. Я пробовал CDC, но я не мог понять, где хранятся измененные значения столбца. Основная цель здесь - отслеживать изменения и показывать их в DataGridView. – user2614235

Смежные вопросы