2016-11-17 61 views
1

我在更新时设置了一个触发器。SQL Server触发器触发但结果奇怪

如果我更新10行,第一个IF块将插入10行到changelog的 但是接下来的IF语句将只更新一行...不是10

第一个IF语句IF @attribute <> 'totalDescriptionLong'必火的10倍,正如我所料。

下一个IF语句IF @attribute = 'publishingStatus' 似乎只火一次......即使我更新10点或更多的行有资格获得这个...!

我不明白为什么代码的一部分在其他

ALTER TRIGGER [dbo].[AttributeUpdate] 
ON [DemandwareDataHub].[dbo].  [RETAILEXPORTOUTPUTEXTHUBDWATTRIBUTE] 
AFTER UPDATE 
AS 
    DECLARE @nOldValue int, @nNewValue int, 
      @attribute nvarchar(60), @attributeValue nvarchar(1999) 

    SELECT @nNewValue = i.Active 
    FROM inserted i 

    SELECT @nOldValue = d.Active FROM deleted d 
    SELECT @attribute = i.ATTRIBUTE FROM inserted i 
Select @attributeValue = i.ATTRIBUTEVALUE from inserted i 

IF @attribute <> 'totalDescriptionLong' 
BEGIN 
    IF @nOldValue <> @nNewValue 
    BEGIN 
     IF EXISTS(SELECT * FROM Inserted) 
     BEGIN 
      INSERT INTO [DemandwareDataHub].[dbo].[ChangeLog] (ReferenceRecid, EntityTypeID, ActionType, LogEntryDateTime, PimChangeDateTime, Processed) 
      --values(  2, 1, 1, getdate(),getdate(),0) 
      SELECT  i.RECID, 1, 1, getdate(), i.TIMESTAMP,0 from Inserted i 
      --INSERT INTO ChangeLog (ReferenceRecid, EntityTypeID, ActionType) VALUES  (1, 1, 1) 
     END 
    END 
    ELSE 
    BEGIN 
     IF EXISTS(SELECT * FROM Inserted) 
     BEGIN 
      INSERT INTO [DemandwareDataHub].[dbo].[ChangeLog] (ReferenceRecid, EntityTypeID, ActionType, LogEntryDateTime, PimChangeDateTime, Processed) 
      --values(  2, 1, 1, getdate(),getdate(),0) 
      SELECT  i.RECID, 1, 2, getdate(), i.TIMESTAMP,0 from Inserted i 
      --INSERT INTO ChangeLog (ReferenceRecid, EntityTypeID, ActionType) VALUES  (1, 1, 1) 
     END 

    END 
END 

IF @attribute = 'publishingStatus' 
BEGIN 
    Declare @Product bigint, @Site nvarchar(60) 
    Select @Product = i.PRODUCT from inserted i 
    Select @Site = i.SITE from inserted i 

    IF @attributeValue = 'proofedPriceCheck' 
    BEGIN 
     --This product has been proofed and is ready for a price check 
     Declare @PriceLocked bit 
     set @PriceLocked = 0 
     SELECT  TOP (1) @PriceLocked = a.PRICELOCKED 
     FROM   RETAILEXPORTOUTPUTEXTDWPRICELOCKED AS a INNER JOIN 
           SyncPimPriceBooks AS b ON a.ACCOUNTRELATION = b.CountryID 
     WHERE  (a.PRODUCT = @Product) AND (b.SiteID = @Site) 

     IF @PriceLocked = 1 
     BEGIN 
      UPDATE  RETAILEXPORTOUTPUTEXTHUBDWATTRIBUTE 
      SET    ATTRIBUTEVALUE = 'proofed' 
      WHERE  (PRODUCT = @Product) AND (SITE = @Site) AND (ATTRIBUTE = 'publishingStatus') 
     END 
     ELSE 
     BEGIN 
      UPDATE  RETAILEXPORTOUTPUTEXTHUBDWATTRIBUTE 
      SET    ATTRIBUTEVALUE = 'proofedPriceNotLocked' 
      WHERE  (PRODUCT = @Product) AND (SITE = @Site) AND (ATTRIBUTE = 'publishingStatus') 
     END 
    END 

END 
+0

你是如何确定它是唯一进入第二IF块只有一次?我相信这很明显,但是你是否获得了attribute =“publishingStatus”AND attributeValue =“proofedPriceCheck”的10个实例? – Forty3

+2

你触发了一个主要的缺陷。它假定只有一行插入。每次操作时,sql server中的触发器都会触发一次。您的触发器需要基于设置,而不是使用从插入拉取的标量值。 –

+0

@ Forty3不......一个UPDATE TOP(10),将晋级第二IF的只会改变一行要么“发面”或“proofedPriceNotLocked”,但它会给我10列的changelog(第一IF) –

回答

2

的另一种方式,我认为这应该是八九不离十的作用。我对插入相当有信心,但更新可能需要稍微调整。当然,我大部分时间都在猜测,因为我没有桌子结构,也不能100%确定你要做什么。这应该是非常接近,但。

insert [DemandwareDataHub].[dbo].[ChangeLog] 
(
    ReferenceRecid 
    , EntityTypeID 
    , ActionType 
    , LogEntryDateTime 
    , PimChangeDateTime 
    , Processed 
) 
select i.RECID 
    , 1 
    , case when i.Active <> d.Active then 1 else 2 end 
    , getdate() 
    , i.TIMESTAMP 
    , 0 
from inserted i 
join deleted d on d.RECID = i.RECID --or whatever the primary key column(s) are 


UPDATE RETAILEXPORTOUTPUTEXTHUBDWATTRIBUTE 
set ATTRIBUTEVALUE = case when re.PRICELOCKED = 1 then 'proofed' else 'proofedPriceNotLocked' end 
from inserted i 
join SyncPimPriceBooks b on b.SiteID = i.SITE 
join RETAILEXPORTOUTPUTEXTDWPRICELOCKED re on re.ACCOUNTRELATION = b.CountryID AND re.PRODUCT = i.PRODUCT 
where re.ATTRIBUTE = 'publishingStatus' 
+1

在这里有正确的想法。在任何情况下都不应该将插入或删除表中的值设置为标量变量。这些表可以包含多个记录,并且该变量只能包含一个值。这是你的问题的原因。您应该始终加入这些表中,或将值设置为表变量。 – HLGEM