0

私たちのアプリの1つでは、ファイルからデータを読み込み、それをいくつかのテーブルに展開します。ファイルの一部が破損している場合は、読み取りを停止し、挿入されたデータをすべて削除します。

ここでの問題は、インポートテーブルの1つに自動インクリメントIDがあり、問題のあるファイルを削除すると、IDはインポート前の値ではなく、インポート後の値から継続することです。

言い換えると...

  • IDは50から始まります。
  • 100レコードを挿入すると、最大IDは150になります。
  • 100レコードを削除しますが、最大IDは150のままです。
  • 50レコードを挿入します。IDは200です。

100レコードの範囲を「失いました」。自動インクリメントに相当する「自動デクリメント」はありますか?

4

4 に答える 4

3

自動採番はあなたにとってそれほど意味のあるものであってはなりません。彼らの保証は、彼らが独自性を提供することだけです。sql server を使用している場合でも再シードできますDBCC CHECKIDENT

Checks the current identity value for the specified table and, if it is needed, changes the identity value. You can also use DBCC CHECKIDENT to manually set a new seed value for the identity column.

BOL から: 次の例では、AdventureWorks データベースの Employee テーブルの現在の ID 値を強制的に 30 にします。

USE AdventureWorks;
GO
DBCC CHECKIDENT ('HumanResources.Employee', RESEED, 30);
GO

私はこれを推奨しているわけではありませんが、指摘するだけです。 DBCC CHECKIDENTすでに使用されている値に再シードしようとすると、エラーがスローされる可能性があります。その場合、そのようなタスクに依存している場合はロジックが必要になります。

なぜこれらの数字がそれほど重要なのかという思考プロセスに疑問を感じます。インクリメントまたはデクリメントなどで呼び出される 1 つの追加フィールドが必要なように思えLineNumberますが、この場合でも、削除されたレコードの後に​​来る行を処理する必要があります。したがって、50 行あり、25 行を削除した場合、25 より大きい行の番号を付け直す必要があります。

UPDATE 
       MyTable 
SET LineItemNumber = LineItemNumber - 1 
WHERE 
       LineItemNumber > @LineItemNumberToBeDeleted  
于 2012-05-11T20:25:47.263 に答える
2

削除時の自動デクリメントは悪い考えのように聞こえます。誤って実行すると、コードにさらに大きなバグを挿入し始める可能性があります。ID が重要な場合は、バッチ番号と、バッチ内のすべてのアイテムの増分 ID を指定してみてください。順次ではありませんが、guid を使用することもできます。

于 2012-05-11T20:27:08.570 に答える
2

次のようにして AutoIncrement ID を再シードできます。

DBCC CHECKIDENT
(
  tablename

  [, [NORESEED | RESEED [, newreseedvalue]]]
)

ただし、これをベスト プラクティスとしてはお勧めしません。クエリはアトミックである必要があります (テーブルをコミットして更新するか、失敗した場合はロールバックします (ID は変更しません)。アトミック クエリを実装するには、TRANSACTION.

BEGIN TRY
   BEGIN TRANSACTION @TranName;

     -- Your database logic here

    COMMIT TRANSACTION @TranName;

END TRY

BEGIN CATCH

   ROLLBACK TRAN @TranName;

END CATCH

GO

ソース:

http://msdn.microsoft.com/en-us/library/ms188929.aspx

http://www.techrepublic.com/blog/datacenter/how-do-i-reseed-a-sql-server-identity-column/406

于 2012-05-11T20:27:32.233 に答える
0

私の経験では、ETL (Extract Transform Load) プロセスのこの部分のベスト プラクティスは、一括読み込みを複数のステップで実行することです。

  1. この目的のためだけに存在する空の「ロード」または「ステージング」テーブルにファイルからデータをロードします。これにより、ファイル レベルの破損が検出されます。
  2. データの参照整合性およびその他の検証を確認します。これにより、データ レベルのエラーが検出されます。
  3. 有効なデータのみを「実際の」テーブルに挿入します。これにより、不要な削除が回避され、自動インクリメント値の浪費が回避されます。
  4. インポート チェックに失敗したデータを記録またはレポートします。
  5. このプロセスを次に実行する直前に、「ロード中」のテーブルを切り捨てます。

于 2012-05-12T17:31:39.497 に答える