Sql 控制ID序列但接受自定义ID而不重复

Sql 控制ID序列但接受自定义ID而不重复,sql,sql-server,Sql,Sql Server,我需要为订单建议一个ID,不能重复前缀+序列号。 问题是用户还可以键入自己的ID 由于表非常大,我考虑创建一个辅助表,其中只包含最后建议的ID和前缀,这样可以更轻松地搜索新的数字 例如: Suggested: 20-001 Suggested: 20-002 User typed: EX901 User typed: 20-004 (!) Suggested: 20-003 Suggested: 20-005 (!) User typed: 20-002 (Invalid) 我想我可

我需要为订单建议一个ID,不能重复前缀+序列号。 问题是用户还可以键入自己的ID

由于表非常大,我考虑创建一个辅助表,其中只包含最后建议的ID和前缀,这样可以更轻松地搜索新的数字

例如:

Suggested: 20-001   
Suggested: 20-002  
User typed: EX901
User typed: 20-004 (!)
Suggested: 20-003
Suggested: 20-005 (!)
User typed: 20-002 (Invalid)
我想我可以创建一个表和一个序列来管理ID:

CREATE SEQUENCE OrderIdSequence
       START WITH 1
       INCREMENT BY 1;
GO;

CREATE TABLE dbo.Order_Ids (
    ID_Order_Ids int IDENTITY(1, 1) NOT NULL PRIMARY KEY,
    Prefix varchar(3) DEFAULT ('') NOT NULL, --Current year as YY.
    Suggested varchar(4) DEFAULT ('') NOT NULL, --Number generated by the sequence.
    Typed varchar(255) DEFAULT ('') NOT NULL, --User typed ID.
    Used BIT NOT NULL Default 0
)
ON [PRIMARY]
当用户键入一个已经存在的ID作为前缀+建议号码时,我将在保存表单时进行验证

我的问题是如何获取下一个序列号,如果它已作为“类型化”列存在,则跳过:

将当前年份前缀为'YY'+'-'+序列

是否可以让insert获取下一个序列,并检查该编号是否已经存在? 也许一个存储过程会更好

我所创造的: 不确定这是否是最好的方法,但我的程序如下:

CREATE PROCEDURE [dbo].[SuggestOrderProcedure] AS
BEGIN
    DECLARE @sequential int = 0;
    DECLARE @prefix varchar(3) = '';
    SELECT @prefix = FORMAT(GETDATE(), 'yy-');

    -- searches for a sequential number that is not being used.
    WHILE @sequential < 1 Or (Select Count(*) FROM Order_Ids WHERE RTRIM(LTRIM(Typed)) = CONCAT(@prefix, RIGHT('0000' + @sequential, 4))) > 0
    BEGIN
       SELECT @sequential = NEXT VALUE FOR dbo.OrderIdSequence;
    END

    -- Inserts the suggested ID into the table Order_Ids.
    INSERT INTO Order_Ids (Prefix, Suggested) OUTPUT Inserted.ID_Order_Ids, Inserted.Prefix, Inserted.Suggested VALUES(@prefix, RIGHT('0000' + @sequential, 4));
    return
END

奇怪的是,当通过Dapper执行时,建议的列返回时没有前导零。

我的建议是以下过程

首先,为表创建一个标识列。默认id应该是一个简单的数字——不多也不少

第二,允许用户指定一个id,但它是一个备用id。它可以是用户想要的任何东西,除了数字。可以使用检查约束强制执行此操作

第三,将备用ID存储在单独的表中,如下所示:

create table alternate_ids as (
    alternate_id varchar(255) primary key,
    user_id int,
    constraint fk_alternate_user foreign key (user_id) references users(user_id),
    constraint chk_alternate_id check (alternate_id like '%[^0-9]]%')
);

查询用户时,如果有字符串,则需要检查备用id,如果没有,则需要检查用户id。或者,您可以使用用户id的字符串表示形式为每个用户填充备用id,而不使用备用id。

问题在于用户键入的订单id也可以是数字。我的问题是进行选择以获得正确的生成ID。