通过 SQL table 循环生成唯一的随机 ID

Generate unique random IDs looping through SQL table

此问题与此 thread 有关,不确定我是否应该 post 那个 post 中的这个新问题或创建一个新的 post,但是担心它可能不会被视为旧 post ...

中的后续问题

这是基于集合的方法的尝试大纲

    DECLARE @r varchar(8);
    SELECT oid, startdate, enddate,
        coalesce(@r, '') + n
        FROM (SELECT TOP 8 
        CHAR(number) n FROM
        master..spt_values
        WHERE type = 'P' AND 
        (number between ascii(0) and ascii(9)
        or number between ascii('A') and ascii('Z')
        or number between ascii('a') and ascii('z'))
        ORDER BY newid()) 
    as externalid
    FROM MasterTable

虽然你的循环不是我处理问题的方式(基于集合的方法要好得多),但你的问题是你没有在循环内重新初始化 @r

所以,添加:

set @r = NULL;

到循环的开头。

我没有对此进行测试,但您可以用此 UPDATE 语句替换循环。它要求您当前的 enternalid 值是唯一的:

WITH cte AS (
    SELECT
        externalid,
        concat(
            substring(chars, num % 62, 1),
            substring(chars, (num/62) % 62, 1),
            substring(chars, (num/3844) % 62, 1),
            substring(chars, (num/238328) % 62, 1),
            substring(chars, (num/14776336) % 62, 1),
            substring(chars, (num/916132832) % 62, 1),
            substring(chars, (num/56800235584) % 62, 1),
            substring(chars, (num/3521614606208) % 62, 1)
        ) AS unique_string8 
    FROM (
        SELECT
            externalid,
            (rn * 34524689549219 + seed) % 199689672115897 AS num,
            '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' AS chars
        FROM (
            SELECT externalid,
                   ROW_NUMBER() OVER (ORDER BY externalid) AS rn,
                   0 AS seed
            FROM   tempmaster
        ) AS subq1
    ) AS subq2
)
UPDATE     t
SET        externalid = cte.unique_string8
FROM       tempmaster t
INNER JOIN cte
        ON cte.externalid = t.externalid;

想法是 cte 查询将您现有的 externalid 映射到新的 8 字符密钥,然后使用执行更新该映射。

这些字符取自具有 62 个可能字符的文字字符串。值 num 是素数加上一些种子(在本例中为 0)的倍数,并通过对接近可能字符串数的素数取模来保持在限制范围内8 个字符。

然后将生成的数字转换为 8 个字符的字符串,就好像该数字要以 62 进制表示一样。公式中的分母是62的次方

这样可以保证您永远不会重复(除非您的记录多于可能的 8 个字母组合)。

没有随机部分,因此它会始终生成相同的系列,但您可以将 seed 值更改为任何整数以更改将生成的系列。