1

データを挿入するSQLスクリプトがあります(現在数千のINSERTステートメントを介して)列の1つに、いくつかの異なるテーブル間で実際に一意の一意の識別子(IDENTITY型ではなく、単なる古いint)が含まれています。

次の利用可能な ID (つまり、最後に使用された ID + 1) を取得するスカラー関数をスクリプトに追加したいのですが、グローバルまたはUDF 内から静的変数を使用することができないため、一時テーブルを使用できず、関数内から永続テーブルを更新できません。

現在、私のスクリプトは次のようになっています。

   @v_baseID int を宣言する
   exec dbo.getNextID @v_baseID out --sproc で次に使用可能な ID を取得します
   -- これらの多く - n はハードコードされた値です
   tableOfStuff (someStuff, uniqueID) 値に挿入 ('stuff', @v_baseID + n )
   exec dbo.UpdateNextID @v_baseID + lastUsedn --sproc を使用して、最後に使用された ID を更新します

しかし、私はそれを次のようにしたいと思います:

   -- たくさん
   tableOfStuff (someStuff, uniqueID) 値 ('stuff', getNextID() ) に挿入します。

オフセットをハードコーディングするのは骨の折れる作業であり、エラーが発生しやすくなります。単純なスカラー関数にパッケージ化することは非常に魅力的ですが、呼び出し間のオフセット カウンターを維持する方法がないように見えるため、その方法では実行できないと考え始めています。そうですか、それとも何か足りないものがありますか。

現在、SQL Server 2005 を使用しています。

明確化のための編集:

2 人のユーザーがヒットすることはありません。これは一度だけ実行され、同時に実行されることのないアップグレード スクリプトです。

実際の sproc の前に sp_ が付いていないため、サンプル コードを修正しました。

通常の使用では、必要に応じて ID テーブルと sproc を使用して ID を取得します。このスクリプトでそれを行うためのよりクリーンな方法を探していました。基本的には、一連のデータを db にダンプするだけです。

4

3 に答える 3

2

2 人のユーザーが同時にヒットすると、同じ ID が取得されます。代わりにIDを持つIDテーブルを使用しなかったのはなぜですか、それに挿入して、それを一意の(保証されている)IDとして使用すると、これもはるかに高速に実行されます

sp_getNextID

proc の前に sp_ を付けることは決してありません。オプティマイザは最初にマスター DB をチェックしてその proc がそこに存在するかどうかを確認し、次にローカル DB をチェックするため、MS がサービス パックで sp_getNextID を作成することを決定した場合も、パフォーマンスに影響します。

于 2008-08-26T15:05:58.943 に答える
2

呼び出し間でオフセット カウンターを維持する方法がないように見えるので、そのようにはできないと思い始めています。そうですか、それとも私が見逃しているものがありますか。

あなたは何も見逃していません。SQL Server はグローバル変数をサポートしておらず、UDF 内のデータ変更もサポートしていません。また、 CONTEXT_INFO を使用するような厄介なことをしたい場合でも ( http://weblogs.sqlteam.com/mladenp/archive/2007/04/23/60185.aspxを参照)、UDF 内からそれを設定することはできません。とりあえず。

それを変数にして、その反復をループし、そのループ内で挿入を行うことで、オフセットの「ハードコーディング」を回避できる方法はありますか?

于 2008-08-27T07:14:44.853 に答える
0

それはおそらく価値があるよりも多くの作業になるでしょうが、SQL CLR UDF で静的 C#/VB 変数を使用できるので、UDF が実行されるたびにこの変数を単純にインクリメントするだけで、やりたいことを実行できると思います。呼ばれた。もちろん、アプリドメインがアンロードされるたびに、静的変数は失われます。したがって、ある日から次の日に ID を継続する必要がある場合は、NextId の最初のアクセス時に、この ID を使用するすべてのテーブルをポーリングして最高値を見つける方法が必要です。

于 2008-08-27T06:07:01.257 に答える