2016-11-17 59 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