使用字母前缀创建自定义序列

时间:2017-06-28 08:15:42

标签: sql-server

我在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的下一个块时,可以使用哪些方法来递增字母?

4 个答案:

答案 0 :(得分:2)

更新和警告

使用主键用于显示的业务键,开票很常见。业务密钥必须存储和编制索引,因为业务用户将使用它来搜索记录,文档等。但您不应使用业务密钥作为主键。

<强> ORIGINAL

您已获得@n/10000的第一位数字。将其添加到65以获得第一个字母。

要获取余数,您可以执行模运算@n/10000并将结果格式化为字符串:

select char(65 + @n/10000) + format(@n % 10000 ,'d')

序列和FORMAT都在SQL Server 2012中引入,因此您可以放心,FORMAT始终可用。

9999将返回A999919999将返回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)