2009-02-18 32 views
7

Có truy vấn tsql nào để biết giá trị cột nhận dạng máy chủ SQL mà nó dự kiến ​​sẽ sử dụng cho chèn hàng tiếp theo không?Làm thế nào để bạn cho biết cột nhận dạng tiếp theo sẽ là gì?

Edited thêm:

Tôi đã xóa và tái tạo một bảng với

[personID] [int] IDENTITY(1,1) NOT NULL 

như một phần của lệnh CREATE TABLE tôi. Tôi cũng đã cố gắng chèn sẵn các cột nhận dạng trong khi xóa tất cả thông tin trong bảng đó và điều đó không phải lúc nào cũng hiệu quả. Nó đã cho tôi để tự hỏi nếu có một cách để xem những gì SQL dự kiến ​​sẽ sử dụng cho số cột nhận dạng tiếp theo của bạn.

+0

Không phải là tôi biết, nhưng tại sao bạn muốn biết? Vấn đề ảnh lớn là gì? – colithium

+0

Nếu bạn muốn xóa nhanh bảng, 'truncate table' sẽ tự động reseeds bất kỳ cột nhận dạng – SWeko

Trả lời

10

Không, đó không phải là đảm bảo bất kỳ cách nào (mặc dù bạn chắc chắn có thể tìm hiểu những gì giá trị tiếp theo thể được, lệnh khác có thể đi và sử dụng nó trước khi bạn có thể thực hiện bất kỳ sử dụng của nó). Giá trị được đảm bảo duy nhất bạn có thể truy xuất là trước đó giá trị nhận dạng được chèn thông qua SCOPE_IDENTITY() (sẽ trả lại giá trị danh tính được tạo lần cuối cho phạm vi hiện tại).

Đó là câu hỏi lý do tại sao người ta cần biết giá trị trước (khi sử dụng cột nhận dạng được tăng lên tự động).

Nếu bạn cần biết giá trị trước đó, thì tôi khuyên bạn nên tự tạo các id. Bạn có thể làm điều này với một bảng id được khóa trên tên bảng, hoặc nếu bạn có các mối quan tâm về khả năng mở rộng (và bạn đang sử dụng các giao dịch), bạn có thể có một bảng id cho mỗi bảng cần một id sẽ có id được chèn vào (và sau đó tăng dần).

Hoặc, bạn có thể sử dụng GUID và bạn sẽ có thể dễ dàng tạo các mục này ở phía máy khách trước khi gửi nó đến cơ sở dữ liệu của bạn.

+0

, FYI: http://blog.sqlauthority.com/2007/03/25/sql-server-identity-vs-scope_identity -vs-ident_current-retrieve-last-insert-identity-of-record/ – gbn

-1

Vì bạn gieo hạt từ 1 và tăng thêm 1 cái đó.

15

Bạn có thể muốn sử dụng SCOPE_IDENTITY không phải @@ IDENTITY để hạn chế giá trị danh tính trong phạm vi hiện tại. Điều này tránh được các giá trị nhận dạng mới được chèn bởi trình kích hoạt vào các bảng khác chứ không phải bảng mà bạn vừa chèn vào.

Nhưng bạn có thể tính toán được những giá trị bản sắc tiếp theo là

SELECT IDENT_CURRENT('mytable') + IDENT_INCR('mytable') FROM mytable 

Vấn đề là bạn đang không được bảo đảm đó là giá trị. Bạn sẽ phải có một khóa để chèn khác bị từ chối trên bàn khi chạy nó để đảm bảo giá trị là chính xác. Ngoài ra sau khi bạn chạy ra khỏi số nguyên 32 bit, tôi không biết logic là gì. Tôi không biết liệu nó có trượt hay không.

Chỉnh sửa: Tôi vừa kiểm tra điều này (xem dưới đây cho SQL) và nó không trả lại giá trị chính xác khi không có dữ liệu. Và việc khởi đầu lại với DBCC CHECKIDENT ('tablename', gieo hạt, 200) thực sự dẫn đến việc giá trị tiếp theo là 201 không 200.

CREATE TABLE willtest (myid integer IDENTITY(1,1), myvalue varchar(255)) 

SELECT IDENT_CURRENT('willtest') + IDENT_INCR('willtest') 

INSERT INTO willtest (myvalue) 
VALUES ('1') 
INSERT INTO willtest (myvalue) 
VALUES ('2') 
INSERT INTO willtest (myvalue) 
VALUES ('3') 
INSERT INTO willtest (myvalue) 
VALUES ('4') 
INSERT INTO willtest (myvalue) 
VALUES ('5') 
INSERT INTO willtest (myvalue) 
VALUES ('6') 
INSERT INTO willtest (myvalue) 
VALUES ('7') 
INSERT INTO willtest (myvalue) 
VALUES ('8') 

SELECT IDENT_CURRENT('willtest') + IDENT_INCR('willtest') 

DBCC CHECKIDENT ('willtest', RESEED, 200) 

SELECT IDENT_CURRENT('willtest') + IDENT_INCR('willtest') 

INSERT INTO willtest (myvalue) 
VALUES ('200') 
INSERT INTO willtest (myvalue) 
VALUES ('201') 
INSERT INTO willtest (myvalue) 
VALUES ('202') 
INSERT INTO willtest (myvalue) 
VALUES ('203') 
INSERT INTO willtest (myvalue) 
VALUES ('204') 
INSERT INTO willtest (myvalue) 
VALUES ('205') 
INSERT INTO willtest (myvalue) 
VALUES ('206') 
INSERT INTO willtest (myvalue) 
VALUES ('207') 

SELECT IDENT_CURRENT('willtest') + IDENT_INCR('willtest') 

SELECT * FROM willtest 

DROP TABLE willtest 
+0

Tại thời điểm này, chúng tôi thậm chí không thể quyết định xem SCOPE_IDENTITY có phù hợp hơn @@ IDENTITY hay không. Hoặc nếu những điều này có thể áp dụng được. – MarlonRibunal

+0

Phần đó phản hồi đề xuất của casperOne. Bây giờ câu hỏi đã được chỉnh sửa - vấn đề thực sự thú vị hơn. –

+0

bạn không cần 'TỪ mytable' trong truy vấn đầu tiên của bạn –

-1

Sử dụng GUID cột cho khóa chính của bạn. Trừ khi bạn có hàng tỷ bản ghi và hàng nghìn yêu cầu mỗi giây, có thể bạn sẽ không nhận thấy sự khác biệt về hiệu suất.Nhưng trừ khi bạn thích dành quá nhiều thời gian đối phó với các vấn đề ngu ngốc như thế này, bạn sẽ nhận thấy sự khác biệt trong mức độ căng thẳng và tuổi thọ của bạn.

+1

Tôi cầu xin sự khác biệt; vấn đề hiệu suất có thể xảy ra ngay cả khi có khoảng một trăm nghìn bản ghi và rất ít yêu cầu. Xem câu hỏi này, ví dụ: http://stackoverflow.com/questions/1703303/sum-group-performance-and-the-primary-key. Chúng tôi đã chuyển mọi thứ từ danh tính sang GUID vài năm trước và chúng tôi đang bắt đầu hối tiếc việc di chuyển này ... – Heinzi

+2

Bây giờ, đừng sử dụng GUID làm PK trừ khi bạn 1. Biết bạn đang làm gì 2. Đừng làm clustered (xem điểm 1) – gbn

+0

không thực sự trả lời câu hỏi –

4

Đoạn sql sẽ cung cấp cho bạn các giá trị cột sắc tiếp theo (có lẽ nhiều lý do để không lặp lại đoạn này trong mã sản xuất)

declare @nextid int; 
declare @previousid int; 

begin tran 

insert into dbo.TestTable (Col1) values ('11'); 
select @nextid = SCOPE_IDENTITY(); 

rollback tran 

select @previousid = @nextid -1 
DBCC CHECKIDENT('dbo.TestTable', RESEED, @previousid); 
select @nextid 

câu hỏi stackoverflow này cho phép thêm một số thông tin - sql-identity-autonumber-is-incremented-even-with-a-transaction-rollback

0
SELECT IDENT_CURRENT('mytable') + IDENT_INCR('mytable') FROM mytable 
+1

Điều này không giải thích cho các hàng bị xóa ... – HerbalMart

+0

Nó cũng không tính đến ai đó đã cố ý thay đổi số hạt giống tiếp theo, đó là những gì tôi xảy ra quan tâm đến ngày hôm nay. –

+0

Tôi không chắc chắn nếu điều này là cụ thể cho một phiên bản cơ sở dữ liệu nhưng tôi SQL Server 2008 R2, và tôi làm việc tốt, nó vinh danh DBCC reseed, và đã cho tôi các giá trị chính xác. @HerbalMart Nó hoạt động dựa trên Ident_Current và cung cấp cho bạn các giá trị chính xác ngay cả khi bạn đã xóa một số hàng. – Niraj

Các vấn đề liên quan