【问题标题】:How to generate random Base36 IDs如何生成随机 Base36 ID
【发布时间】:2012-03-03 05:56:02
【问题描述】:

有没有办法在 SQL Server 中生成具有已定义字符数的 随机 base36 identifiers

我搜索并发现了许多将 base 36 转换为 int 的示例,反之亦然,但不是随机生成唯一 ID。

【问题讨论】:

    标签: sql sql-server tsql uniqueidentifier


    【解决方案1】:

    这个解决方案有点冗长,但很有效,可以很容易地适应各种需求。这是一些示例输出:

    aapx0k  k4fdbb  vzbl5x
    8vr1bs  gbix1q  g5kctv
    he6e50  m9j0m0  2vz53l
    yw72hs  hgbo5h  3oen9v
    6t4q75  337670  5sf3h4
    yqr35s  xoh4hh  tc0wtf
    w7trkj  lnnpdk  zk2ln1
    1gt7qr  l6m72n  ja5kvm
    kg6f9y  6t3b7a  ujfr0i
    2jatgo  0yv8rv  wvbjfa
    

    请注意,您需要创建一个视图来包装 RAND 的使用,这在 UDF 中是不允许的。所以这个解决方案需要两个 db 对象,一个视图和一个 udf。

    CREATE VIEW ViewRandInt AS (SELECT RAND() * 36 as RandInt)
    GO
    
    CREATE FUNCTION GetRandomBase36Id
    (
        @charCount AS INT
    ) 
    RETURNS VARCHAR(50) AS BEGIN
    
        DECLARE @characters CHAR(36),
                @result VARCHAR(MAX),
                @counter INT,
                @randNum INT
    
        SELECT @characters = '0123456789abcdefghijklmnopqrstuvwxyz',
               @result = '',
               @counter = 0;
    
    
        WHILE @counter < @charCount
        BEGIN
            SELECT @randNum = RandInt FROM ViewRandInt
            SET @result = @result + SUBSTRING(@characters, @randNum+1, 1)
            SET @counter = @counter + 1
        END
    
        RETURN @result;
    
    END
    
    -- Test:
    SELECT dbo.GetRandomBase36Id(6), dbo.GetRandomBase36Id(6), dbo.GetRandomBase36Id(6)
    , dbo.GetRandomBase36Id(6), dbo.GetRandomBase36Id(6), dbo.GetRandomBase36Id(6)
    , dbo.GetRandomBase36Id(6), dbo.GetRandomBase36Id(6), dbo.GetRandomBase36Id(6)
    , dbo.GetRandomBase36Id(6), dbo.GetRandomBase36Id(6), dbo.GetRandomBase36Id(6)
    , dbo.GetRandomBase36Id(6), dbo.GetRandomBase36Id(6), dbo.GetRandomBase36Id(6)
    , dbo.GetRandomBase36Id(6), dbo.GetRandomBase36Id(6), dbo.GetRandomBase36Id(6)
    , dbo.GetRandomBase36Id(6), dbo.GetRandomBase36Id(6), dbo.GetRandomBase36Id(6)
    , dbo.GetRandomBase36Id(6), dbo.GetRandomBase36Id(6), dbo.GetRandomBase36Id(6)
    , dbo.GetRandomBase36Id(6), dbo.GetRandomBase36Id(6), dbo.GetRandomBase36Id(6)
    , dbo.GetRandomBase36Id(6), dbo.GetRandomBase36Id(6), dbo.GetRandomBase36Id(6)
    

    【讨论】:

    • @Kumar:我认为您可能已经接受了答案,然后我才发布了对原始答案中的错误的修复。请获取最新的代码示例。 (原码少了一个字符,当z是随机选择的字符时,最终ID不包括它。)
    【解决方案2】:

    MySQL 版本的 Paul Sasik 的回答:

    注意视图中的重要变化:FLOOR(RandInt * 36) INTO v_randNum

    CREATE VIEW `ViewRandInt` AS (select rand() AS `RandInt`);
    
    DROP function IF EXISTS `GetRandomBase36Id`;
    DELIMITER $$
    CREATE FUNCTION `GetRandomBase36Id`(
        p_charCount INT
    ) RETURNS varchar(50) CHARSET latin1
    BEGIN
    
        DECLARE v_characters CHAR(36);
        DECLARE v_result LONGTEXT;
        DECLARE v_counter INT;
        DECLARE v_randNum INT;
    
        SET v_characters = '0123456789abcdefghijklmnopqrstuvwxyz',
               v_result = '',
               v_counter = 0;
               
        WHILE v_counter < p_charCount
        DO
            SELECT FLOOR(RandInt * 36) INTO v_randNum FROM ViewRandInt;
            SET v_result = Concat(v_result , SUBSTRING(v_characters, v_randNum +1, 1));
            SET v_counter = v_counter + 1;
        END WHILE;
    
        RETURN v_result;
    
    END$$
    DELIMITER ;
    
    -- Test
    SELECT GetRandomBase36Id(6)
    , GetRandomBase36Id(6)
    , GetRandomBase36Id(6)
    , GetRandomBase36Id(6)
    , GetRandomBase36Id(6)
    , GetRandomBase36Id(6);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-21
      • 2021-02-07
      • 2020-11-03
      • 1970-01-01
      • 1970-01-01
      • 2019-07-04
      相关资源
      最近更新 更多