SQL Server - INSERT後の戻り値

INSERTステートメントの後でキー値を取得しようとしています。 例: 私は名前とIDの属性を持つテーブルを持っています。 idは生成された値です。

    INSERT INTO table (name) VALUES('bob');

今私は同じステップでIDを戻したいと思う。これはどうですか?

私たちはMicrosoft SQL Server 2008を使用しています。

211
追加された 著者 Vladimir Vagaytsev,
私はここで便利な答えを見つけました:[ステートメントを返す生成キーと] [1] [1]: stackoverflow.com/questions/4224228/…
追加された 著者 Lars Ladegaard,

10 答え

別のSELECTの必要はありません...

INSERT INTO table (name)
OUTPUT Inserted.ID
VALUES('bob');

これは非IDENTITY列(GUIDなど)でも有効です

343
追加された
ねえ、あなたはSO/SEに寄付しましたか?あなたの最後の投稿は12月14日に掲載されました。それ以来、コメントだけ。
追加された 著者 abatishchev,
@ JonnyLeeds:あなたは変数にそれをすることはできません(テーブル変数がない限り)。 OUTPUTはクライアントまたはテーブルに行きます
追加された 著者 gbn,
@hajikelist:これは非常に端的なケースです。トリガーでSET NCOOUNT ONは通常役立ちます。 stackoverflow.com/questions/1483732/set-nocount-on-usage を参照してください。
追加された 著者 gbn,
@@ IDENTITYは使用しないでください。 SCOPE_IDENTITY、はい、しかし決して@@ IDENTITY。それは信頼できない
追加された 著者 gbn,
少し詳しく説明できますか?この例ではアウトプットはどこにありますか? ドキュメントには、テーブルの例しか示されていません)。理想的には、私はそれを変数に渡すことができます
追加された 著者 Jonny Leeds,
@@ IDENTITY なども使用できます。そして、条項の順序は重要です! (難しい方法を見つけました..)
追加された 著者 Z. Khullah,
@gbn私は同意しません - トリガーは非常に一般的です。 NOCOUNTの設定がそれを修正しているかどうかはわかりません。詳細については、msdnの記事を読んでください。
追加された 著者 hajikelist,
残念ながら、テーブルにトリガを追加すると文が壊れるので、これに頼ることはできません! re: blogs.msdn.com/b/sqlprogrammability/archive/2008/07/11/…
追加された 著者 hajikelist,

新しいID値を取得するには SCOPE_IDENTITY()を使用してください

INSERT INTO table (name) VALUES('bob');

SELECT SCOPE_IDENTITY()

http://msdn.microsoft.com/en-us/library/ms190315.aspx

126
追加された
@ liho1eye - OPはアイデンティティ列名を id と呼んだので、はい。
追加された 著者 Curt,
id がアイデンティティであると仮定すると
追加された 著者 Ilia G,
大規模なシステムでは、同時に多くのSQLが実行される場合はどうなりますか?すべてのリクエストに最後に挿入されたIDを返しますか?
追加された 著者 Shiv,
@ Shiv "SCOPE_IDENTITYは、現在のスコープ内にのみ挿入された値を返します"
追加された 著者 goodies4uall,
INSERT INTO files (title) VALUES ('whatever'); 
SELECT * FROM files WHERE id = SCOPE_IDENTITY();

最も安全な方法は、トリガーを持つテーブルでOUTPUT句の競合に関する既知の問題があるためです。あなたのテーブルに現在トリガがない場合でも、これを非常に信頼できないものにします。誰かが行を追加すると、あなたのアプリケーションが破壊されます。時限爆弾のような行動。

詳細については、msdnの記事を参照してください。

http ://blogs.msdn.com/b/sqlprogrammability/archive/2008/07/11/update-with-output-clause-triggers-and-sqlmoreresults.aspx

30
追加された
@hajikelist私たちはすべて遺産を持っていますが、OUTPUTを上げるトリガーのリスクは低く、必要なものはすべてnocountに設定されています。誰かがトリガを追加している場合、コード化する方法を知っている必要があります(主に制御権を持っていることを意味します)。開発者を訓練する必要があります。SQLのバージョンがもはやなくなると、サポートされているので、トリガーは結果セットを生成しません。 INSTEAD OFトリガーがある場合、SCOPE_IDENTITYが機能しない可能性があるため( stackoverflow.com/questions/908257/… )が失われます。
追加された 著者 gbn,
トリガーでSET NOCOUNT ONを追加しない場合のみ。 docs.microsoft.com/en-us/sql/database-engine/configure-windo‌ ws /…
追加された 著者 gbn,
これは従来の環境のオプションではない@gbn
追加された 著者 hajikelist,
@gbn - 私はちょうどこのようなばかげたことを避けるのが好きです。すべての開発者に「私のアプリステートメントを壊さないでください」を追加することを忘れないでください。 - あなたはそれを維持することができます。 "代わりに"のシナリオははるかに端を発しています。
追加された 著者 hajikelist,

Entity Frameworkはgbnの答えに似た何かを実行します:

DECLARE @generated_keys table([Id] uniqueidentifier)

INSERT INTO Customers(FirstName)
OUTPUT inserted.CustomerID INTO @generated_keys
VALUES('bob');

SELECT t.[CustomerID]
FROM @generated_keys AS g 
   JOIN dbo.Customers AS t 
   ON g.Id = t.CustomerID
WHERE @@ROWCOUNT > 0

出力結果は一時テーブル変数に格納され、クライアントに戻されます。つかまえを知っている必要があります:

insertは2つ以上の行を生成することができるので、変数は複数の行を保持できるので、複数の ID

私はEFが実際のテーブルに戻ってエフェメラルテーブルを結合する理由がわかりません。

しかし、それがEFの役割です。

SQL Server 2008以降のみ。それが2005なら、あなたは運が悪いです。

12
追加された

@@ IDENTITY最後に挿入されたID値を返すシステム関数です。

7
追加された
SCOPE_IDENTITY()についての@ Curtの答えを参照してください。
追加された 著者 zanlok,

After doing an insert into a table with an identity column, you can reference @@IDENTITY to get the value: http://msdn.microsoft.com/en-us/library/aa933167%28v=sql.80%29.aspx

5
追加された
はい、使用しないでください。それはうまく動作しません:X
追加された 著者 H.Ghassami,
@@ IDENTITYを使用しないでください:スコープに安全ではありません。
追加された 著者 gbn,

scope_identityを使用して、変数に挿入したばかりの行のIDを選択し、そのテーブルから任意の列を選択することができます。ここで、id = scope_identityから取得したID

See here for the MSDN info http://msdn.microsoft.com/en-us/library/ms190315.aspx

3
追加された

* Parameter order in the connection string is sometimes important. * The Provider parameter's location can break the recordset cursor after adding a row. We saw this behavior with the SQLOLEDB provider.

行が追加された後、プロバイダは接続文字列の最初のパラメータとして指定されていない限り、行フィールドは使用できません。プロバイダが最初のパラメータ以外の接続文字列にある場合、新しく挿入された行フィールドは使用できません。 Providerを最初のパラメータに移動すると、行フィールドが魔法のように表示されました。

2
追加された
あなたは答えを編集し、改善する必要があります。それは現在騒々しいし、ちゃんと答えたり、試行錯誤して来ていません
追加された 著者 James,
多くのユーザーが、追加したばかりの行を識別するための有効なフィールドを持っていなかったため、おそらくこのページに来ました。この現象は、接続文字列のパラメータの順序を変更するだけで、すぐに新しく追加された行にアクセスできることがわかりました。私はそれが大文字で記述するのが賢明だと思っていました。特に、行IDおよびその行の他のフィールドプロバイダーを最初のパラメーターとして配置するだけで問題は解決します。
追加された 著者 David Guidos,
「騒々しい」というのはどういう意味ですか?あなたはあなたの苦情を説明する必要があります。それはできるだけ簡単です。接続文字列のパラメータの順序を変更すると、挿入後に行データを使用できるかどうかが影響を受けます。
追加された 著者 David Guidos,
このコメントがどのように答えるか、質問された質問にどのように関係しているか教えてください。私はそれが大胆で大胆であるとは思わない。あなたの答えが役に立つと思われる場合、ユーザーはそれを投票します。
追加された 著者 n__o,

insertステートメントにselectステートメントを追加することができます。 整数myInt = table1(FName)の値( 'Fred')に挿入します。 Scope_Identity()を選択します。 これはスケーラが実行されたときにアイデンティティの値を返します。

0
追加された

これは、SQL ServerのID列としてIDを使用するテーブルに挿入するときに、OUTPUT INSERTEDを使用する方法です。

'myConn is the ADO connection, RS a recordset and ID an integer
Set RS=myConn.Execute("INSERT INTO M2_VOTELIST(PRODUCER_ID,TITLE,TIMEU) OUTPUT INSERTED.ID VALUES ('Gator','Test',GETDATE())")
ID=RS(0)
0
追加された