【问题标题】:Updating int column of all rows that satisfy datediff constraint?更新满足 datediff 约束的所有行的 int 列?
【发布时间】:2018-01-31 02:20:57
【问题描述】:

我有一个函数每 30 秒运行一次,我想更新 current time - table.lastStoredTime > 5 minutes 所在的所有行中的一列。

lastStoredTime 是一个日期时间列,我似乎无法正常工作。

尝试(不更新行)

SELECT  
    DATEDIFF(MINUTE, t.lastStoredTime, CURRENT_TIMESTAMP) AS Mtime 
FROM Transaction_tbl t 
WHERE 
    AND DATEDIFF(MINUTE,t.lastStoredTime, CURRENT_TIMESTAMP) > 5

【问题讨论】:

    标签: c# sql sql-server timestamp azure-functions


    【解决方案1】:

    测试设置:

    create table Transaction_tbl (id int identity(1,1) not null, lastStoredTime datetime2(7), intcol int)
    insert into Transaction_tbl 
              select dateadd(minute,-7,sysdatetime()), 0
    union all select dateadd(minute,-6,sysdatetime()), 0
    union all select dateadd(minute,-5,sysdatetime()), 0
    union all select dateadd(minute,-4,sysdatetime()), 0
    union all select dateadd(minute,-3,sysdatetime()), 0
    

    查询:

    /* select */
    select *,
      datediff(minute, t.lastStoredTime, sysdatetime()) as Mtime 
    from Transaction_tbl t 
    where t.lastStoredTime < dateadd(minute,-5,sysdatetime())
    
    /* as an update */
    update t
      set intcol = intcol+1
    output inserted.*
    from Transaction_tbl t 
    where t.lastStoredTime < dateadd(minute,-5,sysdatetime())
    

    rextester 演示:http://rextester.com/TXYXT83237

    选择输出:

    +----+---------------------+--------+-------+
    | id |   lastStoredTime    | intcol | Mtime |
    +----+---------------------+--------+-------+
    |  1 | 2017-08-22 19:31:52 |      0 |     7 |
    |  2 | 2017-08-22 19:32:52 |      0 |     6 |
    |  3 | 2017-08-22 19:33:52 |      0 |     5 |
    +----+---------------------+--------+-------+
    

    更新输出:

    +----+---------------------+--------+
    | id |   lastStoredTime    | intcol |
    +----+---------------------+--------+
    |  1 | 2017-08-22 19:31:52 |      1 |
    |  2 | 2017-08-22 19:32:52 |      1 |
    |  3 | 2017-08-22 19:33:52 |      1 |
    +----+---------------------+--------+
    

    使用case 表达式更新:

    update t
      set intcol = case when t.lastStoredTime < dateadd(minute,-5,sysdatetime()) 
          then intcol+1
          else intcol-1
          end
    output inserted.*
    from Transaction_tbl t 
    

    输出:

    +----+---------------------+--------+
    | id |   lastStoredTime    | intcol |
    +----+---------------------+--------+
    |  1 | 2017-08-22 19:47:14 |      2 |
    |  2 | 2017-08-22 19:48:14 |      2 |
    |  3 | 2017-08-22 19:49:14 |     -1 |
    |  4 | 2017-08-22 19:50:14 |     -1 |
    |  5 | 2017-08-22 19:51:14 |     -1 |
    +----+---------------------+--------+
    

    【讨论】:

    • 感谢您的详细描述。如果不满足不等式,是否可以将列更新为不同的值?
    • @RyanShocker 在这种情况下,您可以使用case 表达式。
    【解决方案2】:

    使用下面的sql语句

    SELECT DATEDIFF(MINUTE, t.lastStoredTime, GetDate()) FROM Transaction_tbl t WHERE DATEDIFF(MINUTE,t.lastStoredTime, GetDate()) > 5

    【讨论】:

    • 你知道为什么 t.lastStoredTime 对我来说是无效的列名吗?列类型是日期时间,它显然存在于我的表中。
    • 我已经在我的一个数据库的表上执行了这个语句,它运行良好。您能否给出执行命令得到的错误文本?
    • 智能感知更新错误是问题所在。需要重新启动,谢谢!
    【解决方案3】:

    如果要更新列,为什么要使用 select 语句?
    您应该使用更新语句:

    UPDATE Transaction_tbl 
    SET <YourColumnName> = <Value>
    WHERE t.lastStoredTime <= DATEADD(MINUTE, -5, GETDATE())
    

    当然,&lt;YourColumnName&gt;&lt;Value&gt; 是占位符。

    请注意,我没有使用DATEDIFF,而是将列的值与当前日期和时间前5分钟的值进行了比较(使用DATEADDGETDATE)。
    原因是使用DATEDIFF 版本会阻止SQL Server 使用任何可能与sql 语句相关的索引(不仅仅是DATEDIFF,任何函数都会这样做)。
    通过将列的实际值与计算值进行比较,SQL Server 可以使用任何可能有助于提高性能的索引。

    【讨论】:

    • 完美,我可以让 SET 也运行 else 条件吗?
    • 因此,如果不满足约束,则 值将设置为 以外的其他值
    • SqlZim 的回答已经涵盖了这个问题。查看带有 case 表达式的部分。
    猜你喜欢
    • 1970-01-01
    • 2020-09-14
    • 1970-01-01
    • 2018-06-16
    • 2012-12-28
    • 1970-01-01
    • 2022-11-10
    • 2015-08-24
    • 1970-01-01
    相关资源
    最近更新 更多