有人有代码吗?寻找随机数函数发生器。我只提供可变长度@NumberLength = 50 等。它可以创建最多 50 位的数字,并存储在 varchar 中。(Bigint 没有存储这么高)我正在使用 Floor Rand、Floor、NewId(),仍然没有收到超过 12 位的答案。
如果有人有解决方案,那就太好了。我需要随机化表中的一列。
谢谢,
注意:需要在函数中,函数由于某种原因不能接受 NewID 或 rand(),所以我有时会使用视图。如果再次使用随机数,没问题,我们可以有一点点重复。
这是一种方法(演示)。
创建一个
CRYPT_GEN_RANDOM
不允许在函数中使用的视图然后在函数中调用它并
A-F
用空字符串替换所有内容。下面使用TRANSLATE
将所有映射B-F
到A
和最终REPLACE
删除所有A
s。您也可以简单地使用 6 嵌套
REPLACE
(如果您使用的是 < 2017 的版本,则无论如何您都必须这样做)从视图返回的字符串比最终所需的最大字符串长 10 倍,以使删除这些字符极不可能留下足够的字符。
然后从中选择
注意:您也可以放弃字符串解析,只使用
CRYPT_GEN_RANDOM
生成三个bigint
粘合在一起的字符串(没有减号),但除非您小心,否则这不太随机。最大值
bigint
很9223372036854775807
明显,最左边的数字是 9 的概率较低。类似地,第二个字符是1
或0
比任何其他数字的概率更大。因为3
只有当前导字符是 时,第二个字符才可能是0-8
。其他职位也存在类似问题,但随着您向右移动,重要性会下降。如果这对您来说不是问题,您可以将三个 bigint 的最右边 17 位连接在一起以获得 51 个字符的数字字符串,然后将其缩减到所需的长度。
和功能
使用在没有冲突的 SQL Server中生成随机数中的示例作为起点,这可能对您有用。
如果您需要少于 50 个字节的随机数,您可以尝试
SUBSTRING
使用所需的长度,并查看可能存在多少重复项以及这些重复项是否可以接受。我对 100 万行进行了测试,发现没有 17 个字符或 40 个字符的重复项(根据您的评论)。以下代码创建一个视图以提供对副作用函数的访问,
CRYPT_GEN_RANDOM
. 该函数多次调用视图CYRPT_GEN_RANDOM
,每次调用都获取一个字节。该函数本身是一个模式绑定的表值函数,可以由 SQL Server 查询优化器“内联”,因此与这种类型的操作一样快。
我创建了一个测试表并用 1,000,000 行填充它:
这是您可能期望使用 TVF 更新
SampleData
表的方式:但是,对于大量行,生成的执行计划使用性能表假脱机从 TVF 生成单行。这导致每一行都具有相同的值,这不是所需的状态。
对于这个特定的设置,如果您只在表中插入 57 行,并运行上述语句,您确实会看到每一行的随机值,因为表假脱机不再存在,并且查询优化器选择为每行执行一次 TVF排在
SampleData
.如果您在 SQL Server 2016 或更高版本上运行,则可以使用新的表提示,
NO_PERFORMANCE_SPOOL
以确保永远不会使用此“优化”。当您将该提示与 join-order-enforcing 提示 结合使用时,无论存在多少行,结果都是表中每一FORCE ORDER
行的随机行。因此,更新语句变为:
“实际”执行计划:
看表:
我们看:
在我旧的慢速工作站上,使用此 TVF 更新 1,000,000 行大约需要 40 秒才能完成。
由于我们将 0 到 255 范围内的各个数字“粘合”在一起,因此数字 1 和 2 的出现次数将高于其他数字;但是,由于您使用它来混淆数据而不是对其进行加密,因此我认为这不会是一个破坏交易的问题。
知道了。嗯..我有一个方法。在大片上可能有点慢:
因为你不能在函数中使用 rand(),所以我在这篇文章中从@Pரதீப் 偷了一个视图:
https://stackoverflow.com/questions/31468836/use-rand-in-user-defined-function#31468878
并对其进行了一些修改,使其看起来像这样:
然后我写了这个小曲子,连接视图的结果:
然后你可以这样称呼它:
更改您输入函数的数字将更改输出的字符串的长度。
显然,正如 Aaron & Erik 所提到的,它不会处理重复项。
现在,它可以处理最多 255 个字符的字符串,但我想你可以返回 varchar(max)。不过,我没有足够的勇气在 SE 上使用 varchar(max) ......
这是我的建议。
此处 Table1 可以是您的任何表。如果它不包含超过 50-60 行并且列数较少,则性能会更好。
这就是我没有选择系统表的原因。
用法
等等。
替代解决方案
它将返回一个字母数字。但它会按你的意愿工作。