我尝试编写一个SQL函数,它生成一个介于1000000和4294967295之间的未使用的唯一ID。我需要数值,所以UUID()都不是解决方案。听起来并不困难,但由于某些原因,当在表上的INSERT语句中调用时,下面的代码不能用作主键的值(当然不是auto_increment)。声明就像INSERT INTO table (id, content) VALUES ((SELECT getRandomID(0,0)), 'blabla bla');
(由于此类函数不允许使用默认值,因此我很快为每个参数提交0并在函数中将其设置为所需的值。)
调用一次并与INSERT或Python代码分开,一切都很好。多次调用,发生了一些奇怪的事情,不仅整个过程而且服务器都可能在REPEAT
内挂起。这个过程甚至不可能杀死/重启;我必须重启机器 - .-
它似乎只为我准备了一些随机值,因为相同的值在一些调用之后一次又一次出现,尽管我实际上认为内部rand()
将是外部{{1}的足够的开始/种子}}。
从Python调用,循环在几轮之后开始挂起,尽管我的测试中的第一个总是产生有用的新ID,因此应该在第一轮之后退出。 WYH?好吧,表是空的......所以rand()
返回0,实际上是离开循环的信号......但事实并非如此。
有什么想法吗? 我在SLES 12.2上运行MariaDB 10.something。这是导出的源代码:
SELECT COUNT(*)...
答案 0 :(得分:1)
略有改善:
SELECT COUNT(*) INTO i FROM `table` WHERE `id` = rnd;
UNTIL i = 0 END REPEAT r;
- >
UNTIL NOT EXISTS( SELECT 1 FROM `table` WHERE id = rnd ) REPEAT r;
不要将任何参数传递给RAND
- 这是为了建立可重复的随机数序列。
mysql> SELECT RAND(123), RAND(123), RAND(), RAND()\G
*************************** 1. row ***************************
RAND(123): 0.9277428611440052
RAND(123): 0.9277428611440052
RAND(): 0.5645420109522921
RAND(): 0.12561983719991504
1 row in set (0.00 sec)
如此简化
SET rnd = FLOOR(rangeStart + RAND() * (rangeEnd - rangeStart));
如果要在可能的输出中包含rangeEnd
,请添加1:
SET rnd = FLOOR(rangeStart + RAND() * (rangeEnd - rangeStart + 1));