質問
一番良い入手方法は何ですか IDENTITY
挿入された行の?
については知っています @@IDENTITY
そして IDENT_CURRENT
そして SCOPE_IDENTITY
しかし、それぞれの長所と短所を理解していません。
誰かが違いとそれぞれをいつ使用すべきかを説明してもらえますか?
解決
@@IDENTITY
すべてのスコープにわたって、現在のセッション内のテーブルに対して生成された最後の ID 値を返します。 ここで注意が必要です, 、それはスコープをまたいでいるからです。現在のステートメントの代わりに、トリガーから値を取得できます。SCOPE_IDENTITY()
現在のセッションおよび現在のスコープ内のテーブルに対して生成された最後の ID 値を返します。 一般的に使いたいもの.IDENT_CURRENT('tableName')
任意のセッションおよび任意のスコープ内の特定のテーブルに対して生成された最後の ID 値を返します。これにより、上の 2 つが必要なものではない場合に備えて、どのテーブルから値を取得するかを指定できます (激レア)。また、@としてガイ・スターバック 「レコードを挿入していないテーブルの現在の IDENTITY 値を取得したい場合は、これを使用できます。」の
OUTPUT
句 のINSERT
ステートメントを使用すると、そのステートメントを介して挿入されたすべての行にアクセスできるようになります。特定のステートメントに範囲が限定されているため、次のようになります。 より単純な 上記の他の機能よりも。ただし、少しです より冗長な (テーブル変数/一時テーブルに挿入してクエリを実行する必要があります)、ステートメントがロールバックされるエラー シナリオでも結果が得られます。ただし、クエリで並列実行プランを使用する場合、これは 唯一保証された方法 ID を取得するため (並列処理をオフにすることは除く)。ただし実行される 前に トリガーであり、トリガーによって生成された値を返すために使用することはできません。
他のヒント
挿入された ID を取得する最も安全で正確な方法は、output 句を使用することだと思います。
たとえば(以下から抜粋) MSDN 記事)
USE AdventureWorks2008R2;
GO
DECLARE @MyTableVar table( NewScrapReasonID smallint,
Name varchar(50),
ModifiedDate datetime);
INSERT Production.ScrapReason
OUTPUT INSERTED.ScrapReasonID, INSERTED.Name, INSERTED.ModifiedDate
INTO @MyTableVar
VALUES (N'Operator error', GETDATE());
--Display the result set of the table variable.
SELECT NewScrapReasonID, Name, ModifiedDate FROM @MyTableVar;
--Display the result set of the table.
SELECT ScrapReasonID, Name, ModifiedDate
FROM Production.ScrapReason;
GO
私は他の人たちと同じことを言っているので、誰もが正しいです、私はそれをより明確にしようとしているだけです。
@@IDENTITY
クライアントのデータベースへの接続によって最後に挿入されたものの ID を返します。
ほとんどの場合、これは正常に機能しますが、場合によっては、トリガーが実行して未知の新しい行を挿入し、必要な ID ではなく、この新しい行から ID を取得してしまうことがあります。
SCOPE_IDENTITY()
この問題を解決します。最後に取得したものの ID を返します。 あなたが挿入した SQLコード内で あなたが送った データベースに。トリガーが実行されて余分な行が作成された場合でも、間違った値が返されることはありません。万歳
IDENT_CURRENT
誰かが最後に挿入した ID を返します。他のアプリが不運にも別の行を挿入した場合、自分の行の ID ではなく、その行の ID を取得することになります。
安全にプレイしたい場合は、常に使用してください SCOPE_IDENTITY()
. 。固執するなら @@IDENTITY
後で誰かがトリガーを追加しようとすると、コードはすべて壊れてしまいます。
最高(読んでください:最も安全な) 新しく挿入された行の ID を取得する方法は、 output
句:
create table TableWithIdentity
( IdentityColumnName int identity(1, 1) not null primary key,
... )
-- type of this table's column must match the type of the
-- identity column of the table you'll be inserting into
declare @IdentityOutput table ( ID int )
insert TableWithIdentity
( ... )
output inserted.IdentityColumnName into @IdentityOutput
values
( ... )
select @IdentityValue = (select ID from @IdentityOutput)
追加
SELECT CAST(scope_identity() AS int);
insert SQL ステートメントの最後まで、その後
NewId = command.ExecuteScalar()
それを取得します。
@@IDENTITY、SCOPE_IDENTITY、および IDENT_CURRENT は、テーブルの IDENTITY 列に最後に挿入された値を返すという点で類似した関数です。
@@IDENTITY と SCOPE_IDENTITY は、現在のセッションのテーブルで生成された最後の ID 値を返します。ただし、SCOPE_IDENTITY は現在のスコープ内の値のみを返します。@@IDENTITY は特定の範囲に限定されません。
IDENT_CURRENT はスコープやセッションによって制限されません。指定されたテーブルに限定されます。IDENT_CURRENT は、任意のセッションおよび任意のスコープ内の特定のテーブルに対して生成された ID 値を返します。詳細については、「IDENT_CURRENT」を参照してください。
- IDENT_CURRENT テーブルを引数に取る関数です。
- @@身元 テーブルにトリガーがある場合、混乱を招く結果が返される可能性があります
- スコープ_IDENTITY ほとんどの場合、あなたのヒーローです。
Entity Framework を使用すると、内部的に OUTPUT
新しく挿入された ID 値を返す手法
DECLARE @generated_keys table([Id] uniqueidentifier)
INSERT INTO TurboEncabulators(StatorSlots)
OUTPUT inserted.TurboEncabulatorID INTO @generated_keys
VALUES('Malleable logarithmic casing');
SELECT t.[TurboEncabulatorID ]
FROM @generated_keys AS g
JOIN dbo.TurboEncabulators AS t
ON g.Id = t.TurboEncabulatorID
WHERE @@ROWCOUNT > 0
出力結果は一時テーブル変数に格納され、再びテーブルに結合されて、テーブルから行の値が返されます。
注記:なぜ EF が一時テーブルを実際のテーブルに内部結合するのかわかりません (どのような状況で 2 つが一致しないのか)。
しかし、それがEFのやり方です。
このテクニック(OUTPUT
) は SQL Server 2008 以降でのみ使用できます。
@@身元 現在の SQL 接続を使用して挿入された最後の ID です。これは、挿入ストアド プロシージャから返すのに適した値です。新しいレコードに ID を挿入するだけでよく、その後さらに行が追加されたかどうかは気にしません。
スコープ_IDENTITY 現在の SQL 接続を使用して現在のスコープ内に挿入された最後の ID です。つまり、挿入後にトリガーに基づいて 2 番目の IDENTITY が挿入された場合、それは SCOPE_IDENTITY には反映されず、実行した挿入のみが反映されます。率直に言って、これを使用する理由はありませんでした。
IDENT_CURRENT(テーブル名) 接続またはスコープに関係なく、最後に挿入される ID です。レコードを挿入していないテーブルの現在の IDENTITY 値を取得する場合は、これを使用できます。
SQL Server の他のバージョンについては話せませんが、2012 では直接出力しても問題なく動作します。一時テーブルをわざわざ作成する必要はありません。
INSERT INTO MyTable
OUTPUT INSERTED.ID
VALUES (...)
ちなみに、このテクニックは複数の行を挿入するときにも機能します。
INSERT INTO MyTable
OUTPUT INSERTED.ID
VALUES
(...),
(...),
(...)
出力
ID
2
3
4
いつも scope_identity() を使用すれば、他に何も必要ありません。
Insert ステートメントの後にこれを追加する必要があります。そして、データが挿入されているテーブル名を確認してください。挿入ステートメントによって影響を受けた現在の行番号を取得します。
IDENT_CURRENT('tableName')
最後に追加/更新された ID を探している場合、これは少し古いかもしれませんが、古い PHP (正確には 5.5 以前) を使用している人がたくさんいます。詳細については、次の URL を参照してください。 http://php.net/manual/en/function.mysql-insert-id.php
$last = mysql_insert_id();
を作成します uuid
また、それを列に挿入します。そうすれば、uuid を使用して行を簡単に識別できます。