一小时后更新在表格中插入的记录

时间:2016-12-04 13:08:56

标签: sql sql-server triggers

我有一个事务表,其中插入了记录。表结构如下。

CreateDate|TransactionNo|Status

现在,我希望在创建一小时后更改每个交易记录的状态。

对于Ex。如果在上午10点插入记录并且状态为未付,那么我想触发一个事件或触发器,它将记录状态在上午11点更改为PAID。

我该怎么做?

3 个答案:

答案 0 :(得分:0)

不要改变状态!而是添加一个具有您真正想要的状态的计算列:

alter table add real_status as (case when CreateDate >= dateadd(hour, 1, getdate()) then 'Paid' else status end);

(实际上,我会将表格中的列命名为_status,并将其命名为status。然后您必须小心updateinsert s 。)

您也可以使用视图执行此操作。

为什么要使用这种方法?

  • 重复交易很昂贵。
  • 当您想要更改时,值会发生变化。没有延迟等待作业成为计划或由于对表,页面,行,索引等的锁定。
  • 如果数据库出现故障,数据库重新启动时仍然可以正常运行。

答案 1 :(得分:0)

你能解释为什么你需要改变它吗?如果您确定交易是在一小时内支付的,而您只是想向用户显示" PAID"状态。为什么不修改应用程序中的某些代码?例如:用户检查他的交易;如果他的一些交易是在一小时之前创建的,那么就告诉他" PAID"。最后,您可以在SQL Server代理中创建计划以更新今天创建的所有事务。我的解决方案是否适用于您的情况?

编辑 -

如果您不想触摸您的应用程序;您可以创建一个视图并相应地更改状态。

答案 2 :(得分:0)

也许有另一种方法来实现这一点,但我的如下: -

1)在插入后的表格上创建Trigger

此触发器负责执行作业。

2)通过T-SQL创建SQL Server Agent job

这个工作负责在一小时后更新表格。

完成演示:{同时测试}

此演示在一分钟后更新表格。

Create database DBTest
go

use DBTest
go


Create table TblTransaction (CreateDate datetime,
                            TransactionNo int, 
                            Status varchar (10))
go

USE msdb
go
Create procedure [dbo].[sp_add_job_quick] 
@job nvarchar(128),
@mycommand nvarchar(max), 
@servername nvarchar(28),
@startdate nvarchar(8),
@starttime nvarchar(8)
as
--Add a job
EXEC dbo.sp_add_job
    @job_name = @job ;
--Add a job step named process step. This step runs the stored procedure
EXEC sp_add_jobstep
    @job_name = @job,
    @step_name = N'Update Status After one Hour',
    @subsystem = N'TSQL',
    @command = @mycommand
--Schedule the job at a specified date and time
exec sp_add_jobschedule @job_name = @job,
@name = 'MySchedule',
@freq_type=1,
@active_start_date = @startdate,
@active_start_time = @starttime
-- Add the job to the SQL Server Server
EXEC dbo.sp_add_jobserver
    @job_name =  @job,
    @server_name = @servername

go

use DBTest
go

Create Trigger trg_UpdateRecordAfterOneHour on TblTransaction
After insert
as
declare @JobName varchar (100),
        @TransactionNo int,
        @mycommand  varchar (512),
        @startdate varchar (100),
        @startTime varchar(100)

select @TransactionNo = TransactionNo  from inserted
set @JobName = 'MyJob_' + convert(nvarchar(MAX), GETDATE(), 113)
set @mycommand = 'Update DBTest..TblTransaction set status = ''PAID'' where TransactionNo =' + convert(varchar(100), @TransactionNo)
set @startdate =  convert(nvarchar(MAX), GETDATE(), 112)

set @starttime = Replace(convert(varchar(10), dateadd(MINUTE,1,GETDATE()), 108),':','')

exec msdb.dbo.sp_add_job_quick 
                    @JobName , 
                    @mycommand,
                    @@servername,
                    @startdate,
                    @starttime

让我们插入一条记录,然后选择此记录。

insert TblTransaction values (getdate(),1,'UnPaid')

 select * from TblTransaction

<强>结果:

enter image description here

一分钟后再次选择。

 select * from TblTransaction

<强>结果:

enter image description here

快速备注:

1)在一小时而不是一分钟后执行作业,键入HOUR而不是MINUTE

2)SQL Server Express Edition中不提供创建SQL代理作业的功能,对于Enterprise,Business Intelligence,Standard&amp; S,它是available。网络版。

3)默认情况下,安装SQL Server时禁用SQL Server代理服务,除非用户明确选择自动启动该服务。

根据以下评论更新: -

4)创建的作业正在进行一次,根据演示,在创建[dbo].[sp_add_job_quick]时,我通过了1 @freq_type,如下所示:

@freq_type=1

@freq_type的可接受值如下:

╔═══════╦════════════════════════════════════════╗
║ Value ║              Description               ║
╠═══════╬════════════════════════════════════════╣
║     1 ║ Once                                   ║
║     4 ║ Daily                                  ║
║     8 ║ Weekly                                 ║
║    16 ║ Monthly                                ║
║    32 ║ Monthly, relative to freq_interval     ║
║    64 ║ Run when SQLServerAgent service starts ║
║   128 ║ Run when the computer is idle          ║
╚═══════╩════════════════════════════════════════╝

了解更多详情sp_add_schedule (Transact-SQL)