【发布时间】:2012-03-03 05:56:02
【问题描述】:
有没有办法在 SQL Server 中生成具有已定义字符数的 随机 base36 identifiers?
我搜索并发现了许多将 base 36 转换为 int 的示例,反之亦然,但不是随机生成唯一 ID。
【问题讨论】:
标签: sql sql-server tsql uniqueidentifier
有没有办法在 SQL Server 中生成具有已定义字符数的 随机 base36 identifiers?
我搜索并发现了许多将 base 36 转换为 int 的示例,反之亦然,但不是随机生成唯一 ID。
【问题讨论】:
标签: sql sql-server tsql uniqueidentifier
这个解决方案有点冗长,但很有效,可以很容易地适应各种需求。这是一些示例输出:
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)
【讨论】:
z是随机选择的字符时,最终ID不包括它。)
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);
【讨论】: