2014-02-12 38 views
0

我有2個觸發器爲一個特定的表。第一個是INSERT(address_create_tr),第二個是UPDATE(address_update_tr)。 因此,例如,INSERT觸發器:如何禁用sybase 12.0中的級聯觸發器?

CREATE TRIGGER address_create_tr ON Address FOR INSERT AS 
BEGIN 
    Update Address SET createdDate = getdate() FROM inserted WHERE Address.ID =inserted.ID 
END 

更新觸發,除了在於它觸發對UPDATE行動,它更新updatedDate列相同。當我插入新的地址行時,我的問題上升。插入觸發器address_create_tr觸發器和級聯觸發address_update_tr觸發器(這對我來說是不受歡迎的行爲)。這發生在address_create_tr被觸發時,它更新了createdDate字段的特定行,並且當它更新時createdDate它觸發address_update_tr因此updatedDate字段也被設置。所以實際問題:

如何在Sybase 12.0中禁用級聯觸發器?

謝謝

+0

這是對那裏發生的一些容易混淆的命名/動作。我會假設更新觸發器會觸發更新並更改'updatedDate',插入觸發器將在插入時觸發並更改'createdDate'。這似乎不符合您的敘述或您的發佈代碼。 –

+0

@Damien_The_Unbeliever我現在編輯問題,我希望它會更清晰。 – rxn1d

+0

看着你介紹的代碼 「INSERT觸發器:」 - 'address_update_tr' - 'FOR INSERT' - 'SET updatedDate ='。那麼,請您談談「更新觸發器」,並說,它觸發的'INSERT'和更新'createdDate'。 –

回答

1

嵌套觸發器可以在服務器範圍的基礎上被禁用:

sp_configure 'allow nested triggers', 0

然而,你可能想說話,你的DBA,要求在此之前,可能會有一些應用程序影響,防止發生。

觸發器可以對多個事件來寫,在所提供的示例中,觸發器可以被寫入火插入和更新如下:

CREATE TRIGGER address_create_tr ON Address FOR INSERT, UPDATE AS 

DECLARE 
    @mode  char(1) 

BEGIN 

    select 
      @mode = 'I' 

    select 
      @mode = 'U' 
     from 
      deleted    

    -- Only called for inserts 
    Update Address SET createdDate = getdate() FROM inserted WHERE Address.ID =inserted.ID 
     and @mode = 'I' 

    -- Only called for updates 
    Update Address SET updatedDate = getdate() FROM inserted WHERE Address.ID =inserted.ID 
     and @mode = 'U' 

END 
go 

是否觸發被要求插入或更新確定通過刪除表中的行的存在。已刪除的表格包含行之前的「之前的圖像」,所以如果沒有行,則觸發器將被插入。

當@mode =「I」的第一更新僅稱爲,即一個插入件,所述第二獲得更新。

觸發器可以進一步優化的功能組合成一個單一的更新語句,這將提高性能:

CREATE TRIGGER address_create_tr ON Address FOR INSERT, UPDATE AS 

DECLARE 
    @mode  char(1) 

BEGIN 

    select 
      @mode = 'I' 

    select 
      @mode = 'U' 
     from 
      deleted    

    Update Address SET 
      createdDate = 
       case 
        when @mode = 'I' then getdate() else inserted.createdDate 
       end, 
      updatedDate = 
       case 
        when @mode = 'U' then getdate() else inserted.updatedDate 
       end 
     FROM 
      inserted 
     WHERE 
      Address.ID =inserted.ID 

END 
go 

我用下面的表定義和DML來測試這一點:

create table Address (
    ID int, 
    line1 varchar(40), 
    createdDate datetime null, 
    updatedDate datetime null) 
go 

insert into Address (ID, line1) values (1, 'First Insert') 
go 
insert into Address (ID, line1) values (2, 'Second Insert') 
go 
update Address set line1 = 'Updated address' where ID = 2 
go 

結果如下:

1> select * from Address 
2> go 
ID   line1               createdDate      updatedDate      
----------- ------------------------------------------ ------------------------------- ------------------------------- 
      1 First Insert           Feb 16 2015 7:35AM       NULL 
      2 Updated address          Feb 16 2015 7:35AM    Feb 16 2015 7:35AM 

(2 rows affected) 
1> 

測試Sybase在Linux上運行的ASE 15.7。

1> select @@version 
2> go 
--------------------------------------------------------------------------------------------------------------------------- 
Adaptive Server Enterprise/15.7.0/EBF 19495 SMP /P/x86_64/Enterprise Linux/ase157/2820/64-bit/FBO/Fri Sep 16 00:54:35 2011 
(1 row affected) 
1>