如何在SQL中创建/映射基于31进制的"Identity(标识)"列

6

这是我第一次在论坛上提问,因为我通常更喜欢自己研究并找到答案,但是我承认数据库编程是我的软肋。

我想创建一个用于数据库的31进制身份列,或者根据我的阅读,将MAP SQL身份列映射到32进制列。

我试图创建唯一的5位字母数字序列,范围从00000-ZZZZZ。(例如0BG85)

我意识到字母数字代码并不理想,因为最终你的序列会拼出许多不合适的单词,因此我将消除元音字母(a,e,i,o,u)。所以用31进制。这个项目的限制因素是我正在使用Code39条形码实现,它将我限制在0-9和A-Z(只有大写)。

我对数据库编程的了解有限,我的初步想法是查询生成的最后一个ID,然后通过C#类中的算法递增下一个ID。我的直觉和我阅读的所有内容都告诉我,这是执行任务的一种拙劣不雅的方式。

我的研究指向以下几个资源

Custom Auto-Generated Sequences with SQL Server

Convert any integer to a string base 2 through 36

我想知道我是否可以使用第二个链接中的函数

稍作编辑:

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

如果我通过存储过程或触发器(从未使用过触发器)将它发送到身份列的值,这样做是否可行?我走对了吗?
    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

当向此函数发送标识列值时,该功能正常工作。它与我手动计算的测试值完全匹配。 我要真心感谢Namwar Rizvi提供的原始代码示例和Brian Biales(来自我之前发布的第二个链接)为解释和真正分解Namwar的原始函数而做出的贡献。我的老板认为我是个天才,但实际上如果没有互联网和有用的程序员指引我方向,我只能算得上是个门外汉。 希望这能帮助其他人在今后的道路上。
1个回答

1
我知道你有一个解决方案,但是你的脚本有几个小问题:
  • 为什么它返回VARCHAR(63),这个大小有什么特别之处?如果尝试返回VARCHAR(MAX),将会遇到问题,所以我猜你需要知道最大结果是多少?
  • 你检查有效基数在2和36之间,但是在32和36之间的任何值都会耗尽转换数字;
  • 你只想要转换为基数31,为什么要参数化基数?

我重新格式化了一下,得到了这个:

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;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接