Sql server不是唯一的自动增量列

时间:2017-03-07 14:41:09

标签: sql-server auto-increment

假设我的MSSQL Server数据库中有一个名为 [dbo]。[Order] 的表,如下所示:

CREATE TABLE [dbo].[Order] (
    [Id]                INT             IDENTITY (1, 1) NOT NULL,
    [NumberInMonth]     INT             NOT NULL,
    [Amount]            DECIMAL (18, 2) NOT NULL,
    CONSTRAINT [PK_dbo.Order] PRIMARY KEY CLUSTERED ([Id] ASC)
);

我希望 NumberInMonth 列为:

  • 自动递增,以便数据库保证INSERT操作将创建值为 Number =<的新记录。数字的先前值> + 1 在应用程序代码方面没有任何努力
  • 不是唯一的,因此我可以在1月份订购一个订单#18,在2月份订购另一个订单#18(这将与Id字段不同)

而且我想有办法让每个月的第一天重置 NumberInMonth 的计数器

我如何实现它?

1 个答案:

答案 0 :(得分:2)

一个简单的序列可以提供自动递增功能:

CREATE SEQUENCE seq_numberInMonth as int START WITH 1 INCREMENT BY 1;

CREATE TABLE [dbo].[Order] (
    [Id]                INT             IDENTITY (1, 1) NOT NULL,
    [NumberInMonth]     INT             NOT NULL DEFAULT(next value for seq_numberInMonth),
    [Amount]            DECIMAL (18, 2) NOT NULL,
    CONSTRAINT [PK_dbo.Order] PRIMARY KEY CLUSTERED ([Id] ASC)
);

测试:

INSERT INTO [Order] (Amount) VALUES (12.0), (13.0), (14.0)

SELECT *
FROM [Order]

结果:

Id      NumberInMonth   Amount
1       1               12,00
2       2               13,00
3       3               14,00

您可以非常轻松地create a scheduled job每月1日运行并重置序列:

ALTER SEQUENCE seq_numberInMonth RESTART WITH 1 ;  

在t-sql中创建作业可以这样做:(没有测试它,但它应该按照以下链接工作):

How to: Create a SQL Server Agent Job
Create a Job

USE msdb ;  
GO  
EXEC dbo.sp_add_job  
    @job_name = N'seq_numberInMonth reset' ;  
GO  
EXEC sp_add_jobstep  
    @job_name = N'seq_numberInMonth reset',  
    @step_name = N'1st',  
    @subsystem = N'TSQL',  
    @command = N'ALTER SEQUENCE seq_numberInMonth RESTART WITH 1 ;',   
    @retry_attempts = 5,  
    @retry_interval = 5 ;  
GO  
EXEC sp_add_schedule @schedule_name =  'every 1st of the month' 
    , @enabled = 1
    , @freq_type = 16
    , @freq_interval = 1

GO  
EXEC sp_attach_schedule  
   @job_name = N'seq_numberInMonth reset',  
   @schedule_name = N'every 1st of the month';  
GO  
EXEC dbo.sp_add_jobserver  
    @job_name = N'seq_numberInMonth reset';  
GO