如何在 sql server 中生成从 A00001 开始的字符序列

How to generate sequence of characters starting from A00001 in sql server

提问人:vivek v 提问时间:10/13/2022 最后编辑:Zhorovvivek v 更新时间:10/14/2022 访问量:539

问:

我编写了一个sql函数,该函数每次都会生成一个数字序列。 例如:,直到,然后以 开头。AA00001AA00002AA99999AB00001

我知道 SQL Server 中的序列方法,但它只接受数字。

如何实现这一点?谁能帮忙。

提前致谢

sql-server 序列

评论

0赞 Thom A 10/13/2022
这个序列的目标是什么?是充当主键吗?你是否满足于值中的差距,就像 / 一样?这是您希望需要在多个位置生成的东西(例如,当您使用 a 时),还是特定于单个表(例如 )?SEQUENCEIDENTITYSEQUENCEIDENTITY

答:

1赞 Thom A 10/13/2022 #1

这有一些假设,因为我的评论没有得到回应。

首先,我假设你对间隙感到满意,比如 or .关于像 a 或解决方案一样实现它,我在这里使用的解决方案实际上与我在这里使用计算列来定义值相同。这意味着您的表中还需要一个 or 列。IDENTITYSEQUENCESEQUENCEIDENTITYPERSISTEDIDENTITYSEQUENCE

这个解决方案实际上非常简单。对于最后 5 个字符,您只需要 的模数。对于第二个字符,您需要将值除以整数除以 后继得到模块 26,对于第一个字符,它是值除以 然后除以 。10000010000010000026

这将适用于 () 和 () 之间的任何给定值。0'AA00000'67599999'ZZ99999'

CREATE TABLE dbo.YourTable (I int IDENTITY(1,1) CONSTRAINT chk_I_ValidRange CHECK (I >= 1 AND I <= 67599999),
                            YourSequence AS CONCAT(CHAR((I / 100000 / 26)+65),CHAR(((I / 100000)%26)+65),RIGHT(CONCAT('00000',I % 100000),5)) PERSISTED);
GO

INSERT INTO dbo.YourTable
DEFAULT VALUES;
GO
INSERT INTO dbo.YourTable
DEFAULT VALUES;
GO

SET IDENTITY_INSERT dbo.YourTable ON;

INSERT INTO dbo.YourTable(I)
VALUES(7163742),
      (3624),
      (67599999);

SET IDENTITY_INSERT dbo.YourTable OFF;
GO

SELECT *
FROM  dbo.YourTable;
GO

DROP TABLE dbo.YourTable;

db<>fiddle

评论

0赞 Dan Guzman 10/13/2022
请注意,这将生成一个零数字(例如AB00000)。问题尚不清楚,但据我所知,该请求是一个类似于 SQL 2022 的函数,但前 2 个位置带有字母字符。GENERATE_SERIES
0赞 Thom A 10/13/2022
好点子,@DanGuzman,我没有考虑到 00001 的开始(事实上,我觉得这样做会是一个缺陷)
1赞 Dan Guzman 10/14/2022 #2

扩展@Larnu的答案,下面是一个使用 CTE 生成字母数字序列的示例函数。

CREATE FUNCTION dbo.udf_GenerateSequence(@Count int)
RETURNS TABLE
AS
RETURN (
    WITH 
         t10 AS (SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) t(n))
        ,numbers AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS num FROM t10 AS a CROSS JOIN t10 AS b CROSS JOIN t10 AS c CROSS JOIN t10 AS d CROSS JOIN t10 AS e)
    SELECT
        CONCAT(
              CHAR(((num-1) / (99999*26)) % 26 + 65)
            , CHAR(((num-1) / 99999) % 26 + 65)
            , RIGHT('0000' + CAST((num-1) % 99999 + 1 AS varchar(5)), 5)) AS SequenceValue
    FROM numbers
    WHERE
        num <= @Count
        AND num <= 67599324 --avoid rollover
);
GO

在 Azure SQL 数据库和 SQL Server 2022+ 中,可以利用它来生成一系列数字,从而避免 CTE 执行相同的操作。GENERATE_SERIES

CREATE FUNCTION dbo.udf_GenerateSequence(@Count int)
RETURNS TABLE
AS
RETURN (
    SELECT
        CONCAT(
              CHAR(((value-1) / (99999*26)) % 26 + 65)
            , CHAR(((value-1) / 99999) % 26 + 65)
            , RIGHT('0000' + CAST((value-1) % 99999 + 1 AS varchar(5)), 5)) AS SequenceValue
    FROM GENERATE_SERIES(1, @Count)
    WHERE
        value <= @Count
        AND value <= 67599324 --avoid rollover
);
GO