昨天有人在群裡討論SQL Server返回最後一個標識值的三個函數:IDENT_CURRENT、@@IDENTITY、SCOPE_IDENTITY,在些作個標記和小結。
其實MSDN對此有官方解釋:這三個函數都返回最後產生的標識值。 但是,上述每個函數中定義的“最後”的範圍和會話有所不同。
1、IDENT_CURRENT 返回為某個會話和當前範圍中的指定表產生的最新標識值。
如果 IDENT_CURRENT 值為 NULL(因為表從未包含行或已被截斷),IDENT_CURRENT 函數將返回種子值。
2、@@IDENTITY 返回為跨所有範圍的當前會話中的某個表產生的最新標識值。
如果語句未影響任何包含識別欄位的表,則 @@IDENTITY 返回 NULL。 如果插入了多個行,產生了多個標識值,則 @@IDENTITY 將返回最後產生的標識值。 如果語句觸發了一個或多個觸發器,該觸發器又執行了產生標識值的插入操作,那麼,在語句執行後立即調用,@@IDENTITY 將返回觸發器產生的最後一個標識值。 如果對包含識別欄位的表執行插入操作後觸發了觸發器,並且觸發器對另一個沒有識別欄位的表執行了插入操作,則 @@IDENTITY 將返回第一次插入的標識值。 出現 INSERT 或 SELECT INTO 語句失敗或大量複製失敗,或者事務被復原的情況時,@@IDENTITY 值不會恢複為以前的設定。
3、SCOPE_IDENTITY 返回為當前會話和當前範圍中的某個表產生的最新標識值。
SCOPE_IDENTITY 只返回插入到當前範圍中的值;@@IDENTITY 不受限於特定的範圍。
更詳細的介紹,請看MSDN(http://msdn.microsoft.com/zh-cn/library/ms175098.aspx)
我們看MSDN提供的例子:
準備基礎資料:
| 代碼如下 |
複製代碼 |
/********* 返回最後一相標識值的三個方法 ***************/ /********* 3w@live.cn 邀月 ***************/ /********* 準備基礎資料 ***************/ USE TestDb2; GO IF OBJECT_ID(N'tb1', N'U') IS NOT NULL DROP TABLE tb1; GO IF OBJECT_ID(N'tb2', N'U') IS NOT NULL DROP TABLE tb2; GO CREATE TABLE tb1(id int IDENTITY); CREATE TABLE tb2(id int IDENTITY(100,1)); GO CREATE TRIGGER tb1Insert ON tb1 FOR INSERT AS BEGIN INSERT tb2 DEFAULT VALUES END; GO SELECT id FROM tb1; --此時,IDs是Empty SELECT id FROM tb2; --此時,IDs是Empty 開始會話1: /********* 會話1 ***************/ INSERT tb1 DEFAULT VALUES; SELECT @@IDENTITY; /* 返回100 實際上,這是觸發器返回的結果 */ SELECT SCOPE_IDENTITY(); /* 返回1 在查詢前,由第一個Insert語句返回 */ SELECT IDENT_CURRENT('tb2'); /* 返回100 返回插入到tb2的值,在查詢前由觸發器插入 */ SELECT IDENT_CURRENT('tb1'); /* 返回1 返回插入到tb1的值,在查詢前由Insert語句插入 */ 另外開始新的會話2 /********* 會話2 ***************/ SELECT @@IDENTITY; /* 返回Null,因為查詢前沒有Insert動作 */ SELECT SCOPE_IDENTITY(); /* 返回Null 因為在當前範圍當前會話中沒有Insert動作 */ SELECT IDENT_CURRENT('tb2'); /* 返回100 返回tb2的最後一個插入值 */ |
在此補充一下:當前範圍是指當前SQL語句、當前預存程序、或當前觸發器。
為了比較好理解一點,我們可以把唯一帶參數的IDENT_CURRENT函數看作是“老母雞”,它始終管著自己的小雞,不管外面如何變化,它死死盯著自家小雞的變化。而不帶參數的SCOPE_IDENTITY和@@IDENTITY好像是執法的“城管”,把各種外面的“閑事”都攬到自己懷裡,其中,從名字上理解,帶範圍的SCOPE_IDENTITY更像是現場執法的“專項城管”,任意人都可以管,只是權力受到當前“專項內容”(即範圍)的限制,不屬“專項內容的”,它管不了。而@@IDENTITY則像是全天候的“萬能城管”,什麼都逃不過它的魔爪,什麼都要攬到自己懷裡。不知道這樣您好理解點沒?