SCOPE_IDENTITY () для GUID?

94

Может ли кто-нибудь сказать мне, есть ли эквивалент SCOPE_IDENTITY()использования GUID в качестве первичного ключа в SQL Server?

Я не хочу сначала создавать GUID и сохранять как переменную, поскольку мы используем последовательные GUID в качестве наших первичных ключей.

Есть идеи, как лучше всего получить последний вставленный первичный ключ GUID?

bplus
источник

Ответы:

98

Вы можете получить GUID обратно с помощью OUTPUT. Это работает, когда вы также вставляете несколько записей.

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

Ссылка: Изучение предложения OUTPUT в SQL 2005

Роб Гаррисон
источник
2
Как упоминает анишмарокей, вы должны использовать NewSequentialID () для генерации своих GUID, а не NewID ().
Роб Гаррисон,
@RobGarrison Imo, GUID как PK действительно имеет преимущество перед int / bigint в распределенных системах. Если вы нажимаете БД для получения идентификатора, вы также можете использовать int / bigint. NewSequentialID () может использоваться только как ограничение по умолчанию (например, вы не можете явно вставить, используя NewSequentialID ()). Таким образом, я думаю, что в подавляющем большинстве сценариев, где вы можете его использовать, вы все равно должны делать что-то по-другому.
Шив
Предложение OUTPUTвыдает ошибку для любой таблицы, к которой прикреплен триггер вставки.
Кобус Крюгер,
60

Эквивалента SCOPE_IDENTITY () при использовании GUID в качестве первичных ключей не существует, но вы можете использовать предложение OUTPUT для достижения аналогичного результата. Вам не нужно использовать табличную переменную для вывода.

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

GO

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

Приведенный выше пример полезен, если вы хотите прочитать значение от клиента .Net. Чтобы прочитать значение из .Net, вы должны просто использовать метод ExecuteScalar.

...
string sql = "INSERT INTO GuidTest(IntColumn) OUTPUT inserted.GuidColumn VALUES(1)";
SqlCommand cmd = new SqlCommand(sql, conn);
Guid guid = (Guid)cmd.ExecuteScalar();
...
Даниэль
источник
9

вы хотите использовать NEWID ()

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

    select @id

но проблема с кластерным индексом есть в GUID. прочтите и это NEWSEQUENTIALID (). Это мои идеи, подумайте, прежде чем использовать GUID в качестве первичного ключа . :)

аниш
источник
10
«Встроенная функция newsequentialid () может использоваться только в выражении DEFAULT для столбца типа« uniqueidentifier »в операторе CREATE TABLE или ALTER TABLE. Ее нельзя комбинировать с другими операторами для формирования сложного скалярного выражения».
Скотт Уитлок
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

Используя этот поток в качестве ресурса, я создал следующее для использования в триггере:

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;

Может помочь кому-то другому сделать то же самое. Любопытно, есть ли у кого-нибудь что-то плохое, чтобы сказать о производительности, если это плохая идея или нет.

TravisWhidden
источник
перечитав вопрос, я понял, что это действительно не отвечает на вопрос пользователей ... но все же может быть полезно для кого-то, потому что похожие ответы - это тот же тип ответа.
TravisWhidden