1

SQL Server 2005 でこれを行うためのより良い方法があるかどうか疑問に思っています。

実際には、originator_id (0 から 99 までの数値) と 'next_element' (実際には 1 から 999,999 までの連続したカウンターです) を使用しています。それらから6文字の「コード」を作成しようとしています。

originator_id を 100 万倍してからカウンターを加算すると、0 ~ 99,999,999 の数値が得られます。

次に、これを「基数 32」の文字列に変換します。偽の基数 32 です。実際には 0 ~ 9 と AZ のみを使用していますが、分かりやすくするためにいくつかの紛らわしい英数字 (I、O、S、Z) を削除しています。 .

これを行うには、数値を 32 の累乗で割ります。各段階で、各累乗で取得した結果を、選択した文字の配列からの文字のインデックスとして使用します。

したがって、発信者 ID が 61 で NextCodeElement が 9 の場合、コードは「1T5JA9」になります。

(61 * 1,000,000) + 9 = 61,000,009
61,000,009 div (5^32 = 33,554,432) = 1 = '1'
27,445,577 div (4^32 = 1,048,576) = 26 = 'T'
   182,601 div (3^32 = 32,768) = 5 = '5'
    18,761 div (2^32 = 1,024) = 18 = 'J'
       329 div (1^32 = 32) = 10 = 'A'
         9 div (0^32 = 1) = 9 = '9'

だから私のコードは1T5JA9です

以前はこのアルゴリズムを (Delphi で) 動作させていましたが、今は SQL Server 2005 でそれを再作成できるようにする必要があります。ルーチンを取る。それは機能し、コードを生成する (またはコードをコンポーネントに再構築する) ことができます。

しかし、それは少し長く見えます。除算の結果を int に選択する (つまり、実際にキャストする) トリックが必ずしも「正しい」かどうかはわかりません。この種のより良い SQLS アプローチはありますか?の?

CREATE プロシージャー dummy_RP_CREATE_CODE @NextCodeElement int、@OriginatorID int、
  @code varchar(6) 出力
なので
始める
  @raw_num int を宣言します。
  @bcelems char(32) を宣言します。
  @chr int を宣言します。

  select @bcelems='0123456789ABCDEFGHJKLMNPQRTUVWXY';
  select @code='';

  -- 所定の位置にスケーリングされた originator_id を追加します
  select @raw_num = (@OriginatorID * 1000000) + @NextCodeElement;

  -- これを 6 文字のコードに変換します

  -- 5^32
  @chr = @raw_num / 33554432; を選択します。
  select @raw_num = @raw_num - (@chr * 33554432);
  select @code = @code + SUBSTRING(@bcelems, 1 + @chr, 1);

  -- 4^32
  @chr = @raw_num / 1048576; を選択します。
  select @raw_num = @raw_num - (@chr * 1048576);
  select @code = @code + SUBSTRING(@bcelems, 1 + @chr, 1);

  -- 3^32
  @chr = @raw_num / 32768; を選択します。
  select @raw_num = @raw_num - (@chr * 32768);
  select @code = @code + SUBSTRING(@bcelems, 1 + @chr, 1);

  -- 2^32
  select @chr = @raw_num / 1024;
  select @raw_num = @raw_num - (@chr * 1024);
  select @code = @code + SUBSTRING(@bcelems, 1 + @chr, 1);

  -- 1^32
  select @chr = @raw_num / 32;
  select @raw_num = @raw_num - (@chr * 32);
  select @code = @code + SUBSTRING(@bcelems, 1 + @chr, 1);

  -- 0^32  
  select @code = @code + SUBSTRING(@bcelems, 1 + @raw_num, 1);

  -  それでおしまい!
終わり;

この方法が実際に他の方法よりも桁違いに悪い場合を除き、私は最適化について必死に心配していません。

コードは小さなバーストでしか実行されず、おそらく 10 分ごとに 20 または 30 のコードが生成されます。数値の範囲が広いため、コードを事前に計算して巨大なテーブルにしたくありません (特定のインストールでは、コード範囲全体の小さなポケットのみが使用されます)。

ただし、同じ結果を達成するためのより適切な方法、特に除算と減算がおそらくあると確信しています。

建設的な批判、観察、提案は大歓迎です。

4

2 に答える 2

3

SQL Server 2005 を見て、CLR ストアド プロシージャを使用しない理由はありますか? その場合、選択した CLR 言語を使用できます。おそらく、既存の Delphi コードを比較的直接的に移植したものになるでしょう。

于 2008-09-10T23:44:26.123 に答える
0

これは明らかに SQL Server 2005 で実行できますが、ある種のプリコンパイルされた高級言語ルーチンが意味をなす十分な「非データベース性」があると思います。

Interbase/Firebird 用の DLL と、SQL Server 用の T-SQL sproc を作成しましたが、CLR ルーチンは作成したことがありません。面白い練習になります!

于 2008-09-11T11:25:26.857 に答える