web-dev-qa-db-ja.com

データセット挿入のIDENTITY_INSERTをオフにする

古いデータベースから変換されたデータを挿入するためにデータセットを使用しています。要件は、現在のOrder_ID番号を維持することです。

私は使ってみました:

SET IDENTITY_INSERT orders ON;

これは、SqlServer Management Studioにいるときに機能し、正常に実行できます

INSERT INTO orders (order_Id, ...) VALUES ( 1, ...);

ただし、変換スクリプトで使用しているデータセット挿入を介してそれを行うことはできません。基本的には次のようになります。

dsOrders.Insert(oldorderId, ...);

プロセス中にもSQL(SET IDENTITY_INSERTオーダーをON)を実行しました。これは一度に1つのテーブルに対してのみ実行できることを知っています。

私はこの例外を受け続けます:

IDENTITY_INSERTがOFFに設定されている場合、注文テーブルSystem.Data.SqlClient.SqlExceptionに値を挿入しようとすると例外が発生します。テーブル 'orders'のID列に明示的な値を挿入できません。

何か案は?

更新

AlexSとAlexKuznetsovは、Set Identity_Insertが接続レベルの設定であると述べましたが、SqlProfilerでSQLを見ると、いくつかのコマンドに気づきました。

  • 最初 - SET IDENTITY_INSERT DEAL ON
  • 2番目-exec sp_reset_connection
  • 3番目からn-select&insertを含むさまざまなSQLコマンド

常にexec sp_reset_connectionただし、コマンド間では、これがIdentity_Insert設定の値の損失の原因であると思います。

データセットが接続をリセットしないようにする方法はありますか?

27
Nathan Koop

次のオプションがあります。

SET IDENTITY_INSERT orders ON

[〜#〜] on [〜#〜] IDENTITY列を持つテーブルに特定の値(指定したもの)を挿入する機能をオンにします。

SET IDENTITY_INSERT orders OFF

その動作を再度オフにすると、通常の動作(IDENTITY列は自動生成されるため、値を指定できません)が復元されます。

マーク

53
marc_s

ID列に挿入できるように、SET IDENTITY_INSERT [〜#〜] on [〜#〜]を実行したいとします。

それは少し逆に思えますが、それはそれが機能する方法です。

5
Eric Petroelje

すべてが正しく行われているようです。SETIDENTITY_INSERTの順序ONは、正しい方法ですSQL Serverの側。しかし問題は、データセットを使用していることです。あなたが提供したコードから、あなたはtyped dataset-データベースに基づいてVisual Studioで生成されたものを使用していると言えます。

これが当てはまる場合(ほとんどの場合)this datasetには、orderIdフィールドの値を設定できない制約が含まれています。つまり、コードです。 SQL Serverではなく、明示的な値を指定することはできません。データセットデザイナーに移動して、orderIdフィールドのプロパティを編集する必要があります。AutoIncrementとReadOnlyをfalseに設定します。ただし、同じ変更を実行時に実行できます。これにより、orderIdの明示的な値を持つ行をデータセットに追加し、後でそれをSQL Serverテーブルに保存できます(まだSET IDENTITY_INSERTが必要です)。

また、IDENTITY_INSERTは接続レベルの設定であるため、変更をデータベースに保存するために使用するのと同じ接続に対して、対応するSETを正確に実行する必要があることに注意してください。

3
AlexS

AlexSは正解で、問題はInsert_Identityが機能していたことですが、これは接続レベルの設定であるため、トランザクション内でInsert_Identityを設定する必要がありました。

Ryan Whitakerの TableAdapterHelper コードを使用しました

identity_Insertを実行する更新コマンドをテーブルアダプターに作成しました。次に、Identity列を指定して新しいInsertコマンドを作成する必要がありました。次に、このコードを実行しました

SqlTransaction transaction = null;

try
{
     using (myTableAdapter myAdapter = new myTableAdapter())
     {   
         transaction = TableAdapterHelper.BeginTransaction(myAdapter);
         myAdapter.SetIdentityInsert();
         myAdapter.Insert(myPK,myColumn1,myColumn2,...);
     }

     transaction.Commit();
 }
 catch(Exception ex)
 {
     transaction.Rollback();
 } 
 finally
 {
     transaction.Dispose();
 }
1
Nathan Koop

プロファイラーを使用して、SET IDENTITY_INSERTオーダーがオンかどうかを判断します。後続の挿入と同じ接続、および挿入中に実行される正確なSQLから発行されます。

1
A-K

それでも「IDの挿入」で問題が発生する場合は、次のように完全な挿入ステートメントを使用してみてください。

0
user3447006