我在SQL Server中有一个序列
CREATE SEQUENCE dbo.NextBusinessValue
START WITH 1
INCREMENT BY 1 ;
GO
我想使用它生成一个5位数的自定义参考号,使用此序列以A0000格式创建数字。
参考编号的规则是:
1-9999将是A0001 - A9999
10000-19999将是B0000 - B9999
20000-29999将是C0000 - C9999等......
它无法获得需要超过Z的数据量。
我知道我可以使用以下方式收到一封信:
SELECT CHAR(65)
所以这适用于1-9999:
declare @n int = 9999
SELECT CHAR(65) + right('0000' + convert(varchar(10), @n), 4)
但是当它达到10000时会失败。
每次序列到达10000的下一个块时,可以使用哪些方法来递增字母?
答案 0 :(得分:2)
更新和警告
使用主键和用于显示的业务键,开票很常见。业务密钥必须存储和编制索引,因为业务用户将使用它来搜索记录,文档等。但您不应使用业务密钥作为主键。
<强> ORIGINAL 强>
您已获得@n/10000
的第一位数字。将其添加到65以获得第一个字母。
要获取余数,您可以执行模运算@n/10000
并将结果格式化为字符串:
select char(65 + @n/10000) + format(@n % 10000 ,'d')
序列和FORMAT都在SQL Server 2012中引入,因此您可以放心,FORMAT始终可用。
9999
将返回A9999
,19999
将返回B9999
等。
比例可以是参数本身
select char(65 + @n/@scale) + format(@n % @scale ,'d')
答案 1 :(得分:1)
我个人会在您的显示代码中处理这个问题,或者将它作为计算字段添加到表格或视图中。
这可以达到Z:
declare @n int = 9999
-- Gives A9999
SELECT CHAR(@n / 10000 + 65 ) + right('0000' + convert(varchar(10), @n), 4)
SET @n = 10000
-- Gives B0000
SELECT CHAR(@n / 10000 + 65 ) + right('0000' + convert(varchar(10), @n), 4)
SET @n = 10001
-- Gives B0001
SELECT CHAR(@n / 10000 + 65 ) + right('0000' + convert(varchar(10), @n), 4)
SET @n = 20001
-- Gives C0001
SELECT CHAR(@n / 10000 + 65 ) + right('0000' + convert(varchar(10), @n), 4)
SET @n = 200001
-- Gives U0001
SELECT CHAR(@n / 10000 + 65 ) + right('0000' + convert(varchar(10), @n), 4)
SET @n = 300001
-- Gives _0001
SELECT CHAR(@n / 10000 + 65 ) + right('0000' + convert(varchar(10), @n), 4)
答案 2 :(得分:1)
这样的东西?
DECLARE @n INT = 9999;
WHILE @n < 26000
BEGIN
SELECT CHAR(65 + CONVERT(INT, @n / 10000)) + RIGHT('0000' + CONVERT(VARCHAR(10), @n), 4);
SELECT @n = @n + 1;
END;
答案 3 :(得分:0)
(编辑)的
您不应将此作为主键使用,而是计算输出即时的格式。为了加快搜索速度,我建议您使用以下方法计算持久性计算列,您可以将其与索引一起使用。
DECLARE @mockingTbl TABLE(SomeSeqValue INT);
INSERT INTO @mockingTbl VALUES(0),(1),(999),(1000),(9999),(10000),(12345),(50000);
SELECT A.NumeralPart
,B.Rest
,C.StartLetter
,C.StartLetter+REPLACE(STR(A.NumeralPart,4),' ','0') AS YourCode
FROM @mockingTbl AS m
CROSS APPLY(SELECT m.SomeSeqValue % 10000 AS NumeralPart) AS A
CROSS APPLY(SELECT (m.SomeSeqValue-A.NumeralPart)/1000 AS Rest) AS B
CROSS APPLY(SELECT CHAR(B.Rest + ASCII('A'))) AS C(StartLetter)