2017-10-05 11 views
0

1つのトランザクション内に挿入する必要がある行のバッチがあります。最初の行はヘッダーで、後続の行はすべて最初の行を参照する必要があります。最初の行がFKでトランザクション内に挿入されます

これは私が最初の行を挿入しようとしてる方法です:

using (var connection = new SqlConnection(_connectionString)) 
{ 
    connection.Open(); 
    var transaction = connection.BeginTransaction(); 

    try 
    { 
     // create the record header 
     using (var createRecordCommand = connection.CreateCommand()) 
     { 
      createRecordCommand.CommandText = 
       "DECLARE @RecordId INT;" + 
       $"INSERT INTO ..." + 
       "SET @RecordId = scope_identity();"; 

      createRecordCommand.Transaction = transaction; 
      createRecordCommand.ExecuteNonQuery(); 

私は、その後の文でレコードIDを参照するために苦労しています、変数@RecordIdは、以下のスニペットの中で宣言されていないと考えているようです。 'スカラー変数 "@RecordId"を宣言する必要があります。'

using (var createAttributeCommand = connection.CreateCommand()) 
{ 
    createAttributeCommand.Transaction = transaction; 

    createAttributeCommand.CommandText = 
     $"INSERT INTO ... (RecordId,...) VALUES (@RecordId,...)"; 

またパラメータは難しい証明される@RecordId変数を抽出し、私はDECLARE @RecordId INT;

createRecordCommand.Parameters.Add(new SqlParameter("@RecordId", SqlDbType.Int) { Direction = ParameterDirection.Output }); 
+1

なぜあなたはあなたのロジックは、ストアドプロシージャの中に入れていないし、そしてちょうどC#のからプロシージャを呼び出しますか? –

+0

私は問題の複雑さを無くしました。私たちが達成しようとしていることは、残念なことにストアドプロシージャにとっては複雑すぎます。 –

+1

何か?ストアドプロシージャにはあまりにも複雑ですか?挿入をストアド・プロシージャとして実行し、OUTPUTパラメータを使用してIDを戻します。 –

答えて

0

私はあなたを実現していなかったと一緒に以下の行を使用する場合、それを好きではありませんExecuteScalar()が機能しなかったので、同じ問題が発生したと仮定して、トランザクションがコミットされる前にデータを抽出できます。

コメントで指摘されているように、ストアドプロシージャはおそらく最善の解決策であり、SQLエキスパートはしばらくして壊れたレコードのように聞こえる; p。これは可変パラメータ数が存在するため、短期間では複雑すぎるでしょう。検証と値はビジネスロジックに基づいて変化します。チームとしては、C#の方が快適です。ロジックが完全に打ち切られるまで、ロジックが残る場所です。

結果コードは次のとおりです。N.B.実際のコードでは、SQLインジェクションを防ぐためにパラメータとしてすべての変数を渡し、我々は、このデモはあるだけ

using (var connection = new SqlConnection(_connectionString)) 
{ 
    connection.Open(); 
    var transaction = connection.BeginTransaction(); 

    try 
    { 
     // create the record header 
     using (var createRecordCommand = connection.CreateCommand()) 
     { 
      createRecordCommand.CommandText = 
       //"DECLARE @RecordId INT;" + 
       $"INSERT INTO ..." + 
       "SET @RecordId = scope_identity();"; 

      createRecordCommand.Transaction = transaction; 
      createRecordCommand.Parameters.Add(new SqlParameter("@RecordId", SqlDbType.Int) { Direction = ParameterDirection.Output }); 
      createRecordCommand.ExecuteNonQuery(); 

      recordId = (int) createRecordCommand.Parameters["@RecordId"].Value; 

// ... 

using (var createAttributeCommand = connection.CreateCommand()) 
{ 
    createAttributeCommand.Transaction = transaction; 
    createAttributeCommand.CommandText = 
     $"INSERT INTO ... (RecordId,...) VALUES ({recordId},...)"; 

// ... 

transaction.Commit(); 
関連する問題