關於SQLServer2005的學習筆記——約束、Check、觸發器的執行順序

bq_wang發表於2010-01-08
Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE通常我們認為一條Insert就是一個事務,但這個事務是如何執行的呢?如果保障事務執行時該事務的完整性和一致性呢?拋開儲存機制、索引、鎖等環節,讓我們看看約束、Check和觸發器在這個過程中的先後順序,或許能加深些對事務的理解。

 

CREATE TABLE TestTable

(

  ID         INT    CONSTRAINT PK_TestTable_id PRIMARY KEY,

  UniqueID   INT    UNIQUE,

  Number     INT    CHECK (Number >= 10 AND Number<=100),

  NonNULL    INT    NOT NULL

);

CREATE TABLE LogTable

(

  LogDesc    VARCHAR(50),

  LogDate    DATETIME

);

 

CREATE TRIGGER [TRI_TestTable] ON TestTable

AFTER INSERT,UPDATE

AS

  INSERT INTO LogTable VALUES('TestTable',GETDATE());

 

驗證步驟,第一步插入新值,OK

INSERT INTO TestTable(ID,UniqueID,Number,NonNULL) VALUES(1,1,11,10);

 

插入一條不滿足所以約束和Check條件的記錄,提示不能將值 NULL 插入列 'NonNULL'

INSERT INTO TestTable(ID,UniqueID,Number,NonNULL) VALUES(1,1,1,NULL);

 

NULL值修改為10,繼續插入,提示違反了 PRIMARY KEY 約束 'PK_TestTable_id'

INSERT INTO TestTable(ID,UniqueID,Number,NonNULL) VALUES(1,1,1,10);

 

ID1改為修改為2,繼續插入,提示違反了 UNIQUE KEY 約束 'UQ__TestTable__023D5A04'

INSERT INTO TestTable(ID,UniqueID,Number,NonNULL) VALUES(2,1,1,10);

 

UniqueID1改為修改為2,繼續插入,提示NSERT 語句與 CHECK 約束"CK__TestTable__Numbe__03317E3D"衝突

INSERT INTO TestTable(ID,UniqueID,Number,NonNULL) VALUES(2,2,1,10);

 

Number1改成11,插入OK

INSERT INTO TestTable(ID,UniqueID,Number,NonNULL) VALUES(2,2,11,10);

注意以上只有執行成功後,才會執行觸發器;而如果某個環節失敗,整個事務回滾。

 

再次修改觸發器,注意本處是把Number設定為1,來判斷觸發器執行後,是否仍需要進行Check和約束判斷

ALTER TRIGGER [TRI_TestTable] ON TestTable

AFTER INSERT,UPDATE

AS

  DECLARE @ID INT,@UniqueID INT,@Number INT,@NonNULL INT

  SELECT @ID=ID,@UniqueID=UniqueID,@Number=Number,@NonNULL=NonNULL

FROM INSERTED

  SET @Number=1

  SET @NonNULL=NULL

  INSERT INTO LogTable VALUES('TestTable',GETDATE());

  UPDATE TestTable SET Number=@Number,NonNULL=@NonNULL WHERE ID=@ID

再執行符合所有約束和Check條件的語句

INSERT INTO TestTable(ID,UniqueID,Number,NonNULL) VALUES(3,3,10,10);

提示訊息 515,級別 16,狀態 2,過程 TRI_TestTable,第 9

不能將值 NULL 插入列 'NonNULL',表 'test.dbo.TestTable';列不允許有空值。UPDATE 失敗。

 

SELECT * FROM TestTable

SELECT * FROM LogTable

 

由此可以看出

Insert語句執行時首先驗證約束,同時約束本身也有先後順序

 1、驗證非空約束

 2、驗證主鍵約束

 3、驗證唯一性約束

再次驗證相關Check

最後執行觸發器,如果觸發器中也必須保證不違反相關約束和Check

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/6517/viewspace-624670/,如需轉載,請註明出處,否則將追究法律責任。

相關文章