sql - 控制 ID 序列但接受自定义 ID 而不重复
问题描述
我需要为不应重复的订单建议一个 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')+ '-' + 序列。
是否可以插入获取下一个序列,并检查该数字是否已经存在?也许存储过程会更好?
我设法创造的东西:
不确定这是否是最好的方法,但这是我的程序:
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
奇怪的是,在执行 via 时Dapper
,该Suggested
列返回时没有前导零。
解决方案
我的建议是以下过程。
首先,为表创建一个标识列。默认 id 应该是一个简单的数字——不多也不少。
其次,允许用户指定一个id,但它是一个备用id。它可以是用户想要的任何东西,除了数字。您可以通过check
约束来强制执行此操作。
第三,将备用 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,如果您有字符串,user_id
如果没有。或者,您可以为每个用户填充alternate_ids
一个字符串表示形式,而无需替代。user_id
推荐阅读
- apache - 从 SSL mod_rewrite 规则中排除子域
- phalcon - Phalcon Model 按项目受欢迎程度排序(出现次数)
- android - 单击包含 RecyclerView 的 ViewHolder 时如何重定向到另一个活动?
- amazon-web-services - AWS Elastic Beanstalk 中的多容器 Docker 配置无法正确报告增强的运行状况概述
- react-native - 如何提高具有大量标记的 react-native-map 的性能?
- php - 如何将 id 从一页传递到下一页并将其作为外键插入表中
- python - Flask:从外部def返回render_template而不是@app.route的def
- android - android防止后台应用程序在前台启动活动
- math - 坐标轴比例不同时绘制垂线
- node.js - 使用 express 和 graphql 进行身份验证