【发布时间】:2018-11-01 13:28:47
【问题描述】:
我正在尝试预生成一些字母数字字符串并将结果插入表中。字符串的长度为 5。例如:a5r67。基本上我想为客户生成一些可读的字符串,这样他们就可以访问他们的订单,比如
www.example.com/order/a5r67。现在我有一个选择语句:
;WITH
cte1 AS(SELECT * FROM (VALUES('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'),('a'),('b'),('c'),('d'),('e'),('f'),('g'),('h'),('i'),('j'),('k'),('l'),('m'),('n'),('o'),('p'),('q'),('r'),('s'),('t'),('u'),('v'),('w'),('x'),('y'),('z')) AS v(t)),
cte2 AS(SELECT * FROM (VALUES('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'),('a'),('b'),('c'),('d'),('e'),('f'),('g'),('h'),('i'),('j'),('k'),('l'),('m'),('n'),('o'),('p'),('q'),('r'),('s'),('t'),('u'),('v'),('w'),('x'),('y'),('z')) AS v(t)),
cte3 AS(SELECT * FROM (VALUES('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'),('a'),('b'),('c'),('d'),('e'),('f'),('g'),('h'),('i'),('j'),('k'),('l'),('m'),('n'),('o'),('p'),('q'),('r'),('s'),('t'),('u'),('v'),('w'),('x'),('y'),('z')) AS v(t)),
cte4 AS(SELECT * FROM (VALUES('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'),('a'),('b'),('c'),('d'),('e'),('f'),('g'),('h'),('i'),('j'),('k'),('l'),('m'),('n'),('o'),('p'),('q'),('r'),('s'),('t'),('u'),('v'),('w'),('x'),('y'),('z')) AS v(t)),
cte5 AS(SELECT * FROM (VALUES('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'),('a'),('b'),('c'),('d'),('e'),('f'),('g'),('h'),('i'),('j'),('k'),('l'),('m'),('n'),('o'),('p'),('q'),('r'),('s'),('t'),('u'),('v'),('w'),('x'),('y'),('z')) AS v(t))
INSERT INTO ProductHandles(ID, Used)
SELECT cte1.t + cte2.t + cte3.t + cte4.t + cte5.t, 0
FROM cte1
CROSS JOIN cte2
CROSS JOIN cte3
CROSS JOIN cte4
CROSS JOIN cte5
现在的问题是我需要写这样的东西来从表中获取一个值:
SELECT TOP 1 ID
FROM ProductHandles
WHERE Used = 0
我将在Used 列上建立索引,这样它会很快。问题在于它带有顺序:
00000
00001
00002
...
我知道我可以通过NEWID() 订购,但这会慢得多。我知道除非我们指定Order By 子句,否则无法保证订购。需要的是相反的。我需要保证混乱,但不是每次客户创建订单时都通过NEWID() 订购。
我打算这样使用它:
WITH cte as (
SELECT TOP 1 * FROM ProductHandles WHERE Used = 0
--I don't want to order by newid() here as it will be slow
)
UPDATE cte
SET Used = 1
OUTPUT INSERTED.ID
【问题讨论】:
-
如果你想要混乱,为什么你关心他们得到哪个 ID,只要它不被使用?您似乎正在尝试创建简化的 GUID
-
这是一个要求。这不是我的意愿。是的,比如
readable guid。 -
嗯,你可以通过 id 的子字符串随机排序...不确定它是否会表现良好,但它会是随机的
DECLARE @sort int = (SELECT ROUND(((6 - 1 -1) * RAND() + 1), 0)) ORDER BY substring(ID,@sort,5) -
这是为了满足“不为订单发出顺序/容易猜到的标识符”类型的要求吗?
-
我认为没有一种方法可以在不使用该顺序的情况下从表中拉出随机行。也许相反,您可以使插入本身更加随机并获得按 ID 排序的最高值?
标签: sql sql-server