IDENTITY屬性使用


轉自:http://www.cnblogs.com/seusoftware/p/3804333.html

 

一. 獲取IDENTITY列值
插入了數據,有時還需要獲取剛才生成的序列值另作他用,返回給前端也好,或者插入其他將來需要關聯的表。

記得曾經有個面試題:假設當前表IDENTITY列最大值為N,在存儲過程中,對這個表插入1行數據,獲取到的IDENTITY列值有時小於或者大於N+1,可能是什么原因?

獲取IDENTITY列值有三種方式:
(1) IDENT_CURRENT( 'table_name' ) 返回為任何會話和任何作用域中的特定表最后生成的標識值。
(2) @@IDENTITY 返回為當前會話的所有作用域中的任何表最后生成的標識值。
(3) SCOPE_IDENTITY() 返回為當前會話和當前作用域中的任何表最后生成的標識值。

IDENT_CURRENT( 'table_name' ) 針對特定表,是全局的。@@IDENTITY和SCOPE_IDENTITY()針對所有表,區別在於作用域,也就是上下文:
(1) 如果當前INSERT語句上有函數,觸發器等(不同作用域的)對象返回的IDENTITY值,那么@@IDENTITY會取所有表上的最后1個,而不是當前表上的;

(2) SCOPE_IDENTITY()會取當前作用域所有表上最后1個IDENTITY值,被調用的函數,觸發器已經超出了作用域/上下文。所以在使用INSERT后,接着使用SCOPE_IDENTITY()獲取IDENTITY列值,就不會有問題了:

insert test values('z');
select SCOPE_IDENTITY() as curr_value

一個GO語句/批處理,也是一個上下文的分界點,但是SQL語句是順序執行的,所以一個會話里,只要在INSERT之后用SCOPE_IDENTITY()來獲取IDENTITY值是沒問題的。

 

 

二. 在IDENTITY列上做增刪改操作(DML)
(1) 刪除操作沒有問題,直接DELETE即可

delete test where id = 2

(2) 如果要顯式INSERT某個值,需要開啟IDENTITY_INSERT這個SESSION級的選項

set IDENTITY_INSERT test on;
insert test(id,c1) values(3,'c');
set IDENTITY_INSERT test off;
select * from test

(3) 如果要UPDATE IDENTITY列值,無論是否開啟IDENTITY_INSERT這個選項都無法更新

復制代碼
set IDENTITY_INSERT test on;
update test set id = 10 where id = 1
set IDENTITY_INSERT test off;
/*
Msg 8102, Level 16, State 1, Line 1
Cannot update identity column 'id'.
*/
復制代碼

非要修改的話,就得借助中間表,在不含IDENTITY屬性的中間表里做完UPDATE,然后再把數據導回來。中間表可參考上面的腳本。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM