如何在每5分钟运行一次的SQL Server代理作业中仅更新一次列

时间:2019-06-06 21:07:24

标签: sql sql-server sql-update

我只想在每5分钟命中一次的代理作业中只运行一次此代码:

UPDATE mytable
SET text_column = (CONCAT('Added text - ', text_column))
WHERE status IN ('status1', 'status2', 'status3')
  AND other_criteria IN ('other_criteria1', 'other_criteria2', 'other_criteria3');

新记录可能会在白天和晚上的任何时间插入-这就是为什么该作业每5分钟运行一次。

text_column在插入记录时可以为NULL,也可以不为NULL(这无关紧要,但是可以防止我在where子句中使用ISNULL。)

status可能会在作业运行之前即时更改(这也没关系,除了我无法将上述查询更新为仅针对那些指定状态运行,然后再更改状态以确保更新不会再次发生(因为当记录处于任何状态时,可能仍需要进行其他事务)。)

other_criteria通常是静态信息,但绝不是唯一的...

所以,我想发生的基本上是:

5分钟作业运行-新记录= status1&other_criteria1将text_column设置为“ Added_text-(text_column)”

然后,我想避免在下次作业运行时将此记录的文本列设置为“添加的文本-添加的文本-(text_column)”,即使该作业仍与我的where子句中的“状态”和“ other_criteria”匹配。 ..

有可能在我的where子句中没有更具体的说明吗?

2 个答案:

答案 0 :(得分:2)

我会在您的表格中再增加一列

alter yourtable add column WasUpdated smallint default 0

然后在您的语句中添加一个简单的子句。新记录会将其设置为零,并且在第一次更新后将其设置为1,因此一行将仅更新一次。

UPDATE mytable
SET text_column=(CONCAT('Added text - ', text_column))
    ,wasUpdated = 1
WHERE status
IN ('status1', 'status2', 'status3')
AND other_criteria
IN ('other_criteria1', 'other_criteria2', 'other_criteria3')
AND wasUpdated = 0;

除非您在程序中使用select * from等,否则该专栏不会引起任何头痛。

Vitaly Borisov表示您还可以创建一个日期列。使用这种方法,您将确切知道何时更新行。

  alter yourtable add column Updateddate datetime2 

    UPDATE mytable
    SET text_column=(CONCAT('Added text - ', text_column))
        ,Updateddate = getdate()
    WHERE status
    IN ('status1', 'status2', 'status3')
    AND other_criteria
    IN ('other_criteria1', 'other_criteria2', 'other_criteria3')
    AND Updateddate  is null;
Such column won't introduce any headache, unless you have `select * from` in your procedures etc.

答案 1 :(得分:2)

最简单的方法是过滤出添加的文本:

UPDATE mytable
SET text_column=(CONCAT('Added text - ', text_column))
WHERE status IN ('status1', 'status2', 'status3')
AND other_criteria IN ('other_criteria1', 'other_criteria2', 'other_criteria3')
AND text_column NOT LIKE 'Added text - %';