INSERTステートメントの後にKey-Valueを取得しようとしています。例:nameとid属性を持つテーブルを持っています。idは生成された値です。
INSERT INTO table (name) VALUES('bob');
次に、同じステップでIDを取得します。これはどのように行われますか?
Microsoft SQL Server 2008を使用しています。
INSERTステートメントの後にKey-Valueを取得しようとしています。例:nameとid属性を持つテーブルを持っています。idは生成された値です。
INSERT INTO table (name) VALUES('bob');
次に、同じステップでIDを取得します。これはどのように行われますか?
Microsoft SQL Server 2008を使用しています。
回答:
別のSELECTは必要ありません...
INSERT INTO table (name)
OUTPUT Inserted.ID
VALUES('bob');
これは、非IDENTITY列(GUIDなど)でも機能します。
SCOPE_IDENTITY()
新しいID値を取得するために使用します
INSERT INTO table (name) VALUES('bob');
SELECT SCOPE_IDENTITY()
id
アイデンティティを前提とする
id
と呼んだため、そうです。
INSERT INTO files (title) VALUES ('whatever');
SELECT * FROM files WHERE id = SCOPE_IDENTITY();
トリガーのあるテーブルでのOUTPUT句の競合に関する既知の問題があるため、これが最も安全な方法です。テーブルに現在トリガーがない場合でも、これを非常に信頼性の低いものにします。行の下にトリガーを追加すると、アプリケーションが壊れます。時限爆弾のような行動。
より詳細な説明については、msdnの記事を参照してください。
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
出力結果は一時テーブル変数に格納され、クライアントに返されます。落とし穴に注意する必要があります:
挿入は複数の行を生成できるため、変数は複数の行を保持できるため、複数の行を返すことができます
ID
EFが一時テーブルを実際のテーブルに内部結合する理由はわかりません(どのような状況で2つが一致しない場合があります)。
しかし、それがEFの役割です。
SQL Server 2008以降のみ。それが2005年なら、あなたは運が悪い。
Customer
レコードに対する他のすべての変更も「参照」できるようにするためです。たとえばDEFAULT
、一部の列、テーブルのトリガーなどに影響を与える他のDB側ロジックがある場合があります。EFは、エンティティ(オブジェクト)が挿入に使用したため、クライアント側は、IDと、行の現在の状態を表す他のすべてを持つ顧客オブジェクトを取得します。
挿入後に終了するには多くの方法があります
テーブルにデータを挿入する場合、OUTPUT句を使用して、テーブルに挿入されたデータのコピーを返すことができます。OUTPUT句は、OUTPUTとOUTPUT INTOの2つの基本形式を取ります。呼び出し元のアプリケーションにデータを返す場合は、OUTPUTフォームを使用します。データをテーブルまたはテーブル変数に返す場合は、OUTPUT INTOフォームを使用します。
DECLARE @MyTableVar TABLE (id INT,NAME NVARCHAR(50));
INSERT INTO tableName
(
NAME,....
)OUTPUT INSERTED.id,INSERTED.Name INTO @MyTableVar
VALUES
(
'test',...
)
IDENT_CURRENT:任意のセッションで特定のテーブルまたはビューに対して作成された最後のIDを返します。
SELECT IDENT_CURRENT('tableName') AS [IDENT_CURRENT]
SCOPE_IDENTITY:同じセッションおよび同じスコープからの最後のIDを返します。スコープは、ストアドプロシージャ/トリガーなどです。
SELECT SCOPE_IDENTITY() AS [SCOPE_IDENTITY];
@@ IDENTITY:同じセッションの最後のIDを返します。
SELECT @@IDENTITY AS [@@IDENTITY];
out put
しbulk insert
て挿入しましたselect statement
。あなたの提案に感謝
最良かつ最も確実な解決策は SCOPE_IDENTITY()
です。
同じスコープで2つの挿入を呼び出すことができるため、挿入するたびにスコープIDを取得して変数に保存する必要があります。
ident_current
そして@@identity
、彼らは動作しますが、彼らは安全な範囲ではありませんかもしれません。大きなアプリケーションで問題が発生する可能性があります
declare @duplicataId int
select @duplicataId = (SELECT SCOPE_IDENTITY())
詳細はこちらMicrosoft docs
select @duplicataId = SCOPE_IDENTITY()
OUTPUT
節はより良い、より純粋な解決策です:)
使用できます scope_identity()
して、変数に挿入したばかりの行のIDを選択してから、そのテーブルから、id =取得したIDである任意の列を選択することができます。scope_identity()
MSDN情報については、こちらをご覧くださいhttp://msdn.microsoft.com/en-us/library/ms190315.aspx
挿入コマンドの後に最後に挿入されたIDを取得する方法は複数あります。
@@IDENTITY
:テーブルと値を生成したステートメントのスコープに関係なく、現在のセッションの接続で生成された最後のID値を返しますSCOPE_IDENTITY()
:テーブルに関係なく、現在の接続の現在のスコープにあるinsertステートメントによって生成された最後のID値を返します。IDENT_CURRENT(‘TABLENAME’)
:接続、セッション、スコープに関係なく、指定されたテーブルで生成された最後のID値を返します。IDENT_CURRENTはスコープとセッションによって制限されません。指定されたテーブルに限定されます。どちらが私の要件に完全に一致するかを決定することは、より困難に思えます。
私は主にSCOPE_IDENTITY()を好みます。
insertステートメントでTableNameと共にselect SCOPE_IDENTITY()を使用すると、期待どおりの正確な結果が得られます。
出典:CodoBee
これは、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)
ID列を持つテーブルへの挿入を行った後、@@ IDENTITYを参照して値を取得できます。http: //msdn.microsoft.com/en-us/library/aa933167%28v=sql.80%29.aspx
*接続文字列のパラメーターの順序が重要になる場合があります。*行を追加した後、Providerパラメータの場所によってレコードセットカーソルが壊れる可能性があります。SQLOLEDBプロバイダーでこの動作を確認しました。
行が追加された後は、接続文字列の最初のパラメーターとしてプロバイダーが指定されていない限り、行フィールドは使用できません。プロバイダーが接続文字列の最初のパラメーター以外の場所にある場合、新しく挿入された行フィールドは使用できません。プロバイダーを最初のパラメーターに移動すると、行フィールドが魔法のように表示されました。