6

私は通常、自分で調査して答えを見つけることを好むため、フォーラムに質問を投稿するのはこれが初めてですが、データベースプログラミングが私のアキレス腱であることを認めるのに十分なプログラマーです。

データベースで使用する base31 ID 列を作成しようとしています。または、読んでいるものから、MAP SQL ID 列を Base32 列に作成しようとしています。

00000 ~ ZZZZZ の範囲で一意の 5 桁の英数字シーケンスを作成しようとしています。(例 0BG85)

英数字コードは、最終的にあなたのシーケンスが多くのビジネス上不適切な単語を綴るため、理想的ではないことを認識しています。したがって、母音 (a、e、i、o、u) を削除します。したがって、Base31。このプロジェクトの制限要因は、Code39 バーコードの実装を使用しているため、0 ~ 9 と AZ (大文字のみ) に制限されていることです。

私はデータベース プログラミングへの露出が限られており、最初に考えたのは、生成された最後の ID を照会し、C# クラスを介してアルゴリズムを介して次の ID をインクリメントすることでした。私の本能と私が読んできたすべてのことは、これはタスクを実行するための鈍感で洗練されていない方法であると教えてくれました.

私の研究は、これらのいくつかのリソースに私を導きます

SQL Server によるカスタム自動生成シーケンス

任意の整数を基数 2 から 36 の文字列に変換します

2nd Linkの機能を使ったのかな

で少し編集

Declare @alldigits as varchar(31);
Set @alldigits='0123456789BCDFGHJKLMNPQRSTVWXYZ'

ストアドプロシージャまたはトリガーを介してID列の値を送信しました(これまでトリガーを使用したことがありません)。これは受け入れられますか?私は正しい軌道に乗っていますか?

**回答が見つかりましたが、私 (新規ユーザー) はさらに 5 時間自分の回答を投稿できません**

    FUNCTION dbo.CreateBase31ID
    (
@val as BigInt,
@base as int
)
returns varchar(63)
as
Begin
/* From http://sqltips.wordpress.com/2009/01/12/tsql-function-to-convert-decimal-to-hex-octal-or-any-other-base/  */
/* blog text: 
SQL Tips by Namwar Rizvi
  Frequently I see the questions in newsgroups about a function to convert 
  integer value to other bases like base 2 (binary), base 8 (octal) and base 16(hex). 
  Following TSQL function, which was orginally mentioned by Itzik Ben-Gan 
  in his book Inside Microsoft SQL Server 2005:TSQL Querying, provides you the 
  ability to convert a given integer into any target base. 
  I have just updated the function with more meaningful names and added some 
  comments to clear the logic.
*/

  /* Check if value is valid and if we get a valid base (2 through 36) */
  If (@val<0) OR (@base < 2) OR (@base> 36) Return Null;

  /* variable to hold final answer */
  Declare @answer as varchar(63);

  /* Following variable contains all 
     possible alpha numeric letters for any valid base 
  */
  Declare @alldigits as varchar(31);
  Set @alldigits='0123456789BCDFGHJKLMNPQRSTVWXYZ'

  /* Set the initial value of 
     final answer as empty string 
  */
  Set @answer='';

  /* Loop while the source value remains greater than 0 */
  While @val>0
  Begin
    Set @answer=Substring(@alldigits,@val % @base + 1,1) + @answer;
    Set @val = @val / @base;
  End

  /* Return the final answer */
  return @answer;
End

この関数は、ID 列の値を関数に送信するときに正しく機能しています。これは、手動で計算したテスト値に完全に対応しています。Namwar Rizvi の元のコード例と、Namwar の元の機能を説明し、実際に分解してくれた Brian Biales (私の以前の投稿の 2 番目のリンクから) に心から感謝したいと思います。上司は私を天才だと思っていますが、実際には、インターネットや親切なプログラマーが道を教えてくれなかったら、私はただの素人に過ぎなかったでしょう。

これが他の誰かに役立つことを願っています。

4

1 に答える 1

1

解決策があることは知っていますが、スクリプトにはいくつかの小さな問題があります。

  • なぜそれは VARCHAR(63) を返すのですか?そのサイズについて具体的なことは何ですか? VARCHAR(MAX) を返そうとすると問題が発生するので、最大の結果が何であるかを知る必要があると思いますか?
  • 2 から 36 の間の有効な基数をチェックしますが、32 から 36 の間のものは変換桁数を使い果たします。
  • 本当に base 31 に変換したいだけなのに、なぜ base をパラメータ化するのですか?

私はそれを少し再フォーマットし、これを得ました:

FUNCTION BigIntToBase31Ish (
    @Value BIGINT)
RETURNS VARCHAR(255)
AS
BEGIN
    DECLARE @Result VARCHAR(255) = '';
    DECLARE @Base INT = 31;
    DECLARE @ConvertDigits VARCHAR(31) = '0123456789BCDFGHJKLMNPQRSTVWXYZ';

    --Is the integer value valid?
    IF @Value < 0
        RETURN NULL;

    --Convert the integer value to base 31
    WHILE @Value > 0
    BEGIN
        SELECT @Result = SUBSTRING(@ConvertDigits,@Value % @Base + 1, 1) + @Result;
        SELECT @Value = @Value / @Base;
    END;
    RETURN @Result;
END;
于 2013-07-25T14:57:25.647 に答える