SCOPE_IDENTITY () cho GUID?


94

Bất cứ ai có thể cho tôi biết nếu có tương đương với SCOPE_IDENTITY()khi sử dụng GUID làm khóa chính trong SQL Server không?

Tôi không muốn tạo GUID trước và lưu dưới dạng một biến vì chúng tôi đang sử dụng các GUID tuần tự làm khóa chính của mình.

Bất kỳ ý tưởng nào về cách tốt nhất để truy xuất khóa chính GUID được chèn lần cuối?

Câu trả lời:


98

Bạn có thể lấy lại GUID bằng cách sử dụng OUTPUT. Điều này hoạt động khi bạn cũng chèn nhiều bản ghi.

CREATE TABLE dbo.GuidPk (
    ColGuid uniqueidentifier NOT NULL DEFAULT NewSequentialID(),
    Col2    int              NOT NULL
)
GO

DECLARE @op TABLE (
    ColGuid uniqueidentifier
)

INSERT INTO dbo.GuidPk (
    Col2
)
OUTPUT inserted.ColGuid
INTO @op
VALUES (1)

SELECT * FROM @op

SELECT * FROM dbo.GuidPk

Tham khảo: Khám phá Mệnh đề OUTPUT của SQL 2005


2
Như anishmarokey đã đề cập, bạn nên sử dụng NewSequentialID () để tạo GUID của mình chứ không phải NewID ().
Rob Garrison

@RobGarrison Imo, GUID như một PK chỉ thực sự có lợi hơn int / bigint trong các hệ thống phân tán. Nếu bạn đang nhấn DB để tìm nạp ID, bạn cũng có thể sử dụng int / bigint. NewSequentialID () chỉ có thể được sử dụng như một ràng buộc mặc định (bạn không thể chèn rõ ràng bằng NewSequentialID () chẳng hạn). Vì vậy, tôi nghĩ rằng phần lớn các tình huống mà bạn có thể sử dụng nó, bạn nên làm mọi thứ theo cách khác.
Shiv

Các OUTPUTkhoản cho một lỗi trên bất kỳ bảng nào có kích hoạt chèn đính kèm.
Cobus Kruger

60

Không có SCOPE_IDENTITY () tương đương khi sử dụng GUID làm khóa chính, nhưng bạn có thể sử dụng mệnh đề OUTPUT để đạt được kết quả tương tự. Bạn không cần phải sử dụng một biến bảng cho đầu ra.

CREATE TABLE dbo.GuidTest (
    GuidColumn uniqueidentifier NOT NULL DEFAULT NewSequentialID(),
    IntColumn int NOT NULL
)

GO

INSERT INTO GuidTest(IntColumn)
OUTPUT inserted.GuidColumn
VALUES(1)

Ví dụ trên rất hữu ích nếu bạn muốn đọc giá trị từ máy khách .Net. Để đọc giá trị từ .Net, bạn chỉ cần sử dụng phương thức ExecuteScalar.

...
string sql = "INSERT INTO GuidTest(IntColumn) OUTPUT inserted.GuidColumn VALUES(1)";
SqlCommand cmd = new SqlCommand(sql, conn);
Guid guid = (Guid)cmd.ExecuteScalar();
...

9

bạn muốn sử dụng NEWID ()

    declare @id uniqueidentifier
    set @id  = NEWID()
    INSERT INTO [dbo].[tbl1]
           ([id])
     VALUES
           (@id)

    select @id

nhưng vấn đề chỉ mục cụm có trong GUID. đọc cái này quá NEWSEQUENTIALID () . Đây là những ý tưởng của tôi, hãy suy nghĩ trước khi sử dụng GUID làm Khóa chính . :)


10
"Hàm tích hợp newsequentialid () chỉ có thể được sử dụng trong biểu thức DEFAULT cho cột loại 'uniqueidentifier' trong câu lệnh CREATE TABLE hoặc ALTER TABLE. Nó không thể được kết hợp với các toán tử khác để tạo thành một biểu thức vô hướng phức tạp."
Scott Whitlock

4
CREATE TABLE TestTable(KEY uniqueidentifier, ID VARCHAR(100), Name VARCHAR(100), Value tinyint);
Declare @id uniqueidentifier ;  
DECLARE @TmpTable TABLE (KEY uniqueidentifier);     
INSERT INTO [dbo].[TestTable]
    ([ID], [Name], Value])           
    OUTPUT INSERTED.KEY INTO @TmpTable           
    VALUES(@ID, @Name, @Value);           
SELECT @uniqueidentifier = KEY FROM @TmpTable; 
DROP TABLE TestTable;

2

Sử dụng chuỗi này làm tài nguyên, tôi đã tạo phần sau để sử dụng trong trình kích hoạt:

DECLARE @nextId uniqueIdentifier;
DECLARE @tempTable TABLE(theKey uniqueIdentifier NOT NULL DEFAULT NewSequentialID(), b int);
INSERT INTO @tempTable (b) Values(@b);
SELECT @nextId = theKey from @tempTable;

Có thể giúp người khác làm điều tương tự. Tò mò nếu bất cứ ai có bất cứ điều gì xấu để nói hiệu suất khôn ngoan nếu đây không phải là một ý tưởng tốt hay không.


sau khi đọc lại câu hỏi, tôi nhận ra rằng điều này thực sự không trả lời được câu hỏi của người dùng ... nhưng vẫn có thể hữu ích cho ai đó vì các câu trả lời tương tự là cùng một kiểu phản hồi.
TravisWhiised
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.