2012-12-01 155 views
7

我從來沒有見過這種情況發生過,很奇怪。奇怪的SQL Server 2012 IDENTITY問題

我有一個本地開發的SQL Server 2012 Express數據庫。使用TestDrive插件運行一套簡單的測試並使用EF v5訪問數據庫。

我剛剛運行了一個測試,將一條記錄插入到數據庫中。我從表1-9中的表中有9行。下一個插入和ID正好跳過10000!

的ID列雲:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10009 

我知道失敗的刀片也增加了ID,但是我可以保證10,000沒有失敗在5秒之間插入試運行......

表格結構非常簡單,類型爲bigint(long)的一列和一個自動遞增的標識列,沒有SP,觸發器或任何其他程序化內容。

[Id] [bigint] IDENTITY(1,1) NOT NULL, 

很混亂,有沒有其他人看到過這種情況?

+0

我不明白它如何可以是我的代碼。代碼對ID沒有做任何事情,它是一個INSERT命令,而不是UPDATE命令,如果INSERT嘗試應用ID,它將簡單地忽略ID值... – Jammer

+0

似乎這可能是2012年的一個錯誤,因爲它是在其他人報道以及... http://connect.microsoft.com/SQLServer/feedback/details/743300/identity-column-jumps-by-seed-value#tabs我剛剛爲此添加了一個日誌爲以及... – Jammer

+0

似乎它是由重啓SQL引擎造成的......但是爲什麼當我的種子是1時它會跳到10000有點瘋狂...... – Jammer

回答

2

這個blog post有一些額外的細節。它看起來像在2012年,identity被實施爲一個序列。默認情況下,一個序列有一個緩存。如果緩存丟失,則會丟失緩存中的序列值。

所提出的解決方案是用no cache創建序列:

CREATE SEQUENCE TEST_Sequence 
    AS INT 
    START WITH 1 
    INCREMENT BY 1 
    NO CACHE 

據我所看到的,標識列後面的序列是不可見的。您無法將其屬性更改爲禁用緩存。

要在Entity Framework中使用此功能,您可以將主鍵StoredGeneratedPattern設置爲Computed。然後,你可以生成在instead of insert觸發身份服務器端:

if exists (select * from sys.sequences where name = 'Sequence1') 
    drop sequence Sequence1 
if exists (select * from sys.tables where name = 'Table1') 
    drop table Table1 
if exists (select * from sys.triggers where name = 'Trigger1') 
    drop trigger Trigger1 
go 
create sequence Sequence1 
    as int 
    start with 1 
    increment by 1 
    no cache 
go 
create table Table1 
    (
    id int primary key, 
    col1 varchar(50) 
    ) 
go 
create trigger Trigger1 
    on Table1 
    instead of insert 
as 
insert Table1 
     (ID, col1) 
select next value for Sequence1 
,  col1 
from inserted 
go 
insert Table1 (col1) values ('row1'); 
insert Table1 (col1) values ('row2'); 
insert Table1 (col1) values ('row3'); 

select * 
from Table1 

如果你找到一個更好的解決辦法,讓我知道:)

+0

啊......這很有趣。我會看看如果我能得到這個沒有緩存方法與EF工作... – Jammer

+0

嗯...所有對我來說都顯得有些混亂:(我會看看我是否能找到任何有關它的信息並向我彙報 – Jammer

+0

其實,你知道嗎,我甚至不確定我是否在意,這是一個bigint,所以我不打算去我的ID不會以任何方式被使用,這取決於它們是如何創建的,以及它是否僅在SQLServer重新啓動時纔會發生(通常不會出現)(至少我是最後一句話)......至少我現在不關心了,很可能會回到2008 R2來進行真正的生產部署... – Jammer

0

如果將「檢查點」,每個插入查詢後命令調用,它會解決你的問題。

欲瞭解更多的信息,請讀出SQL Server中的檢查點

+0

DB中大約有300個插入查詢。將無法工作,MS需要解決這個問題。 –