GUIDのSCOPE_IDENTITY()?


94

SCOPE_IDENTITY()SQL ServerでGUIDを主キーとして使用する場合に相当するものがあるかどうか誰かに教えてもらえますか?

最初にGUIDを作成して変数として保存したくないのは、シーケンシャルGUIDを主キーとして使用しているためです。

最後に挿入されたGUID主キーを取得する最良の方法について何か考えはありますか?

回答:


98

OUTPUTを使用すると、GUIDを取得できます。これは、複数のレコードを挿入する場合にも機能します。

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

リファレンス:SQL 2005のOUTPUT句の調査


2
anishmarokeyが言及しているように、GUIDの生成にはNewID()ではなくNewSequentialID()を使用する必要があります。
Rob Garrison、

@RobGarrison Imo、PKとしてのGUIDは、分散システムのint / bigintよりも本当に有利です。IDをフェッチするためにDBにアクセスする場合は、int / bigintを使用することもできます。NewSequentialID()はデフォルトの制約としてのみ使用できます(たとえば、NewSequentialID()を使用して明示的に挿入することはできません)。そのため、それを使用できるシナリオの大部分は、とにかく別の方法で行う必要があると思います。
Shiv 2018年

このOUTPUT句は、挿入トリガーがアタッチされているすべてのテーブルでエラーを発生させます。
コバスクルーガー

60

GUIDを主キーとして使用する場合、同等のSCOPE_IDENTITY()はありませんが、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()組み込み関数は、CREATE TABLEまたはALTER TABLEステートメントのタイプ 'uniqueidentifier'の列のDEFAULT式でのみ使用できます。他の演算子と組み合わせて複雑なスカラー式を形成することはできません。」
スコットウィットロック

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 2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.