データセットの挿入でIDENTITY_INSERTをオフにする
-
22-07-2019 - |
質問
データセットを使用して、古いデータベースから変換されるデータを挿入しています。要件は、現在のOrder_ID番号を維持することです。
使用してみました:
SET IDENTITY_INSERT orders ON;
これは、SqlServer Management Studioにいるときに機能し、正常に実行できます
INSERT INTO orders (order_Id, ...) VALUES ( 1, ...);
ただし、変換スクリプトで使用しているデータセットの挿入を介して実行することはできません。基本的には次のようになります:
dsOrders.Insert(oldorderId, ...);
処理中にもSQL(SET IDENTITY_INSERTの順序をオン)を実行しました。一度に1つのテーブルに対してのみこれを行うことができることを知っています。
この例外が引き続き発生します:
ordersテーブルに値を挿入しようとしたときの例外 System.Data.SqlClient.SqlException:IDENTITY_INSERTがOFFに設定されている場合、テーブル 'orders'のID列に明示的な値を挿入できません。
アイデアはありますか
更新
AlexS& AlexKuznetsovはSet Identity_Insertは接続レベルの設定であると述べていますが、SqlProfilerでSQLを見ると、いくつかのコマンドに気づきます。
- 最初-
SET IDENTITY_INSERT DEAL ON
- 2番目-
exec sp_reset_connection
- 3番目からn-select&を含むさまざまなsqlコマンド挿入
コマンド間には常に exec sp_reset_connection
がありますが、Identity_Insert設定の値が失われるのはこれが原因だと思います。
データセットの接続のリセットを停止する方法はありますか?
解決
オプションがまちまちです:
SET IDENTITY_INSERT orders ON
IDENTITY列を持つテーブルに特定の値(指定した値)を挿入する機能を ON にします。
SET IDENTITY_INSERT orders OFF
その動作を再度オフにすると、通常の動作(IDENTITY列は自動生成されるため値を指定できません)が復元されます。
マーク
他のヒント
ID列に挿入できるようにSET IDENTITY_INSERT ON を実行します。
少し後方に見えますが、それが動作する方法です。
すべてを正しく行っているようです。 SQL Server側 では、SET IDENTITY_INSERT orders ONが正しい方法です。しかし問題は、データセットを使用していることです。あなたが提供したコードから、 入力されたデータセット -データベースに基づいてVisual Studioで生成されたものを使用していると言えます。
この場合(ほとんどの場合)、 このデータセット には、orderIdフィールドの値を設定できない制約が含まれています。つまり、そうするコードです。 SQL Serverではなく、明示的な値の指定を許可しません。データセットデザイナーに移動し、orderIdフィールドのプロパティを編集する必要があります。AutoIncrementおよびReadOnlyをfalseに設定します。ただし、実行時に同じ変更を実行できます。これにより、orderIdの明示的な値を含む行をデータセットに追加し、後でSQL Serverテーブルに保存できます(SET IDENTITY_INSERTが必要です)。
また、IDENTITY_INSERTは接続レベルの設定であるため、データベースへの変更を保存するために使用するのと同じ接続に対して正確に対応するSETを実行していることを確認する必要があります。
プロファイラーを使用して、SET IDENTITY_INSERTの注文がオンかどうかを判断します。 後続の挿入と同じ接続、および挿入中に実行されている正確なSQLから発行されます。
AlexSは正しかった、問題はInsert_Identityが機能していたが、それは接続レベルの設定なので、トランザクション内でInsert_Identityを設定する必要がありました。
Ryan Whitakerの TableAdapterHelper コードを使用しました
そして、Identity_Insertを実行するtableadapterで更新コマンドを作成しました。次に、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();
}
" insert_identity"にまだ問題がある場合、次のような完全な挿入ステートメントを使用してみてください:
User(Id、Name)の値(1、 'jeff')に挿入