現在C#で作業していますが、新しいレコードを1つのテーブルに挿入し、新しい主キー値を取得して、それを外部キー参照として使用して、さらにいくつかのレコードを挿入する必要があります。データベースはMSSQLServer2003です。すべてのヘルプに感謝します。
3 に答える
挿入された行の ID を取得する方法は、SCOPE_IDENTITY()
関数を使用することです。ストアド プロシージャを使用している場合、これは次のようになり、行 ID が出力パラメーターとして返されます。
CREATE PROCEDURE dbo.MyProcedure
(
@RowId INT = NULL OUTPUT
)
AS
INSERT INTO MyTable
(
Column1
,Column2
,...
)
VALUES
(
@Param1
,@Param2
,...
);
SET @RowId = SCOPE_IDENTITY();
その後、この値を後続の挿入に使用できます (または、データをすべてストアド プロシージャに渡すことができる場合は、プロシージャ本体の残りの部分で使用できます)。
SQL を動的に渡す場合は、ほとんど同じ手法を使用しますが、ステートメント区切り文字 ( ;
SQL でも) を含む単一の文字列を使用します。たとえば、次のようになります。
var sql = "INSERT INTO MyTable (Column1, Column2, ...) VALUES (@P1, @P2, ...);" +
"SELECT SCOPE_IDENTITY();";
次に、これを使用して実行するExecuteScalar
と、ID をスカラー結果として取得し、正しい型にキャストできます。または、バッチ全体を一度に構築することもできます。
var sql = "DECLARE @RowId INT;" +
"INSERT INTO MyTable (Column1, Column2, ...) VALUES (@P1, @P2, ...);" +
"SET @RowId = SCOPE_IDENTITY();" +
"INSERT INTO MyOtherTable (Column1, ...) VALUES (@P3, @P4, ...);";
これは正確には正しい構文ではないかもしれませんし、最初に使用する必要があるかもしれませんSET NOCOUNT ON;
(私は動的 SQL をめったに使用しないので、私の心は錆びています) が、正しい軌道に乗るはずです。
これを行う最善の方法は、TSQL で SCOPE_IDENTITY() 関数を使用することです。これは、挿入の一部として実行する必要があります。
SqlCommand cmd = new SqlCommand(@"
INSERT INTO T (Name) VALUES(@Name)
SELECT SCOPE_IDENTITY() As TheId", conn);
cmd.AddParameter("@Name", SqlDbType.VarChar, 50).Value = "Test";
int tId = (int)cmd.ExecuteScalar();
または、SCOPE_IDENTITY() を変数に割り当てて、後続のステートメントで使用することもできます。例えば
DECLARE @T1 int
INSERT INTO T (Name) VALUES('Test')
SELECT @T1 = SCOPE_IDENTITY()
INSERT INTO T2 (Name, TId) VALUES('Test', @T1)
SQL のみを使用している場合は、Duncan の回答を確認してください。ただし、LINQ を使用している場合は、エンティティを作成して DB に保存すると、ID パラメータが自動的に設定されます。
ユーザー エンティティとユーザー テーブルを指定すると、次のようになります。
using(var db = new DataContext()) {
var user = new User { Name = "Jhon" };
db.Users.InsertOnSubmit(user);
db.SubmitChanges();
/* At this point the user.ID field will have the primary key from the database */
}