【问题标题】:SQL Most efficient way to create int value from dateTimeSQL 从 dateTime 创建 int 值的最有效方法
【发布时间】:2015-10-06 13:58:57
【问题描述】:

使用 SQL Server 2008 R2,我有一个触发器,它在更新后更新字段。它为每个更新的行插入日期。触发器中的这一行执行此操作:

SET t.lastUpdatedDateTime = CURRENT_TIMESTAMP

使用 yyyymmddhhmmss 上面的行将插入这个 2015-07-16 16:19:00。现在我遇到了一种情况,即企业需要一个整数版本。

实现这一目标的最有效方法是什么。这就是我所拥有的,但它似乎很长而且很贵:

SET t.lastUpdatedDateTimeINT = CAST('' + cast(year(GETDATE()) as varchar(4)) + right('0' + cast((month(GETDATE())) as varchar(2)), 2) + right('0' + cast((day(GETDATE())) as varchar(2)), 2) + right('0' + cast((datepart(hh, GETDATE())) as varchar(2)), 2) + right('0' + cast((datepart(MI, GETDATE())) as varchar(2)), 2) + right('0' + cast((datepart(ss, GETDATE())) as varchar(2)), 2)  as bigint)

有没有更好更有效的方法来做到这一点?期望的结果是 20150716161900

次要问题。我根本不喜欢将日期存储为整数。事实上,在担任当前职位之前,我从未这样做过。我可以就此征求意见吗?避免这种情况的重要理由是什么?在这个组织中偏爱这个有几个原因。这里有一个,每次客户端点击 web 服务时,这个 dateTime 值都会与内容一起传递,当客户端在未来点击 web 服务时,它需要传入这个 dateTime 值以有效地获取最佳数据。简而言之,企业担心这会以不同的形式出现。

已编辑:

这里是完整的触发器:

    ALTER TRIGGER [dbo].[trig_lastUpdated]
    ON [dbo].[AAdeleteMe] 
    AFTER UPDATE
    AS
    BEGIN 
        IF NOT UPDATE(lastUpdatedDateTime)
        BEGIN
            UPDATE t
                 -- my original code (the long way for my result)
                 --SET t.lastUpdatedDateTimeINT = CAST('' + cast(year(GETDATE()) as varchar(4)) + right('0' + cast((month(GETDATE())) as varchar(2)), 2) + right('0' + cast((day(GETDATE())) as varchar(2)), 2) + right('0' + cast((datepart(hh, GETDATE())) as varchar(2)), 2) + right('0' + cast((datepart(MI, GETDATE())) as varchar(2)), 2) + right('0' + cast((datepart(ss, GETDATE())) as varchar(2)), 2)  as bigint)
                 --and here is the solution below (the shortway for my result)
                 --SET t.lastUpdatedDateTimeINT = REPLACE(REPLACE((convert(varchar(10),CURRENT_TIMESTAMP,111) + convert(varchar(8),CURRENT_TIMESTAMP,114)),'/',''),':','')
                --Just discovered the 112 format so managed to drop one replace
                SET t.lastUpdatedDateTimeINT = REPLACE((convert(varchar(10),CURRENT_TIMESTAMP,112) + convert(varchar(8),CURRENT_TIMESTAMP,114)),':','') 
                FROM dbo.AADeleteMe AS t 
                INNER JOIN inserted AS i 
                ON t.ID = i.ID;
        END
    END

    GO

【问题讨论】:

  • 你失去了 date-math 的所有功能并且不得不重写它。玩得开心。再加上它很愚蠢。
  • 告诉您的企业这是一个糟糕的理由。
  • “当客户端将来访问 web 服务时,它需要传入这个 dateTime 值以有效地获取最佳数据”然后以某种方式将 datetime 字段转换为 web 服务中的整数。不要仅仅因为您希望它以某种方式呈现就将其存储为垃圾。当你想以不同的方式呈现它时会发生什么?还是对其进行计算?
  • 感谢您的 cmets。我完全不赞成它,但不是决策者。我知道它的“愚蠢”和“可怕”以及我们失去了所有内置日期功能的事实。我想知道为什么应该审查这个决定是否还有其他角度?再次感谢您的评论
  • 如果业务担心客户无法正确处理datetime等复杂数据类型,想使用简单的int,至少使用标准的方式将日期存储为int。将日期存储为简单的int 的一种广泛传播的方法是 unix 时间。它始终是 UTC。从1970-01-01 到现在只是经过了几秒钟。在任何情况下,您都应该使用bigint,而不是int。尽管如此,我还是会将数据库中的日期存储为datetime,并在与客户交谈时将其转换为unix时间。

标签: sql sql-server tsql triggers sql-server-2008-r2


【解决方案1】:

如果您只想要日期的整数部分,那么解决方案之一就是从日期中删除日期值中的分隔符,例如:- '/'、'-'、':' 和 ' ' 空格,您将获取所需格式的日期:-

SELECT REPLACE(REPLACE(REPLACE ( '2015-07-16 16:19:00' , '-' , '' ),':',''),' ','')

输出:- 20150716161900

See DEMO

更新:-

根据你的要求使用这个

Select REPLACE(REPLACE((convert(varchar(10),CURRENT_TIMESTAMP,101) 
                + convert(varchar(8),CURRENT_TIMESTAMP,114)),'/',''),':','')

如果您的列 lastUpdatedDateTimeINT 是 INT,那么它会引发溢出错误,因此您必须更改该列的数据类型,因为您要分配的值对于 INT 来说非常大

【讨论】:

  • 您好,谢谢您的输入,但由于硬编码“2015-07-16 16:19:00”没有用,因此需要在 CURRENT_TIMESTAMP 上完成替换。如果我尝试这个,我当然会得到 - 将字符串转换为 smalldatetime 数据类型时转换失败
  • 所以你可以转换,没什么大不了的。您在 CURRENT_TIMESTAMP 列中有什么值?
  • 对不起,我完全理解。 CURRENT_TIMESTAMP 不是一列。 lastUpdatedDateTime 是值进入的 int 类型列。我根据你的建议尝试了这个 SET t.lastUpdatedDateTime = REPLACE(REPLACE(REPLACE ( CURRENT_TIMESTAMP , '-' , '' ),':',''),' ','')
  • 是的,非常好。这确实给了我 7172015094553 所以我将 101 日期格式更改为 111 给我 yyyymmdd 并且效果很好。谢谢你。您对此 intDate 要求有意见吗?我将用您的解决方案更新我的原始帖子并接受这一点。再次感谢,祝你有美好的一天
  • 刚刚发现没有分隔符的 112 格式,因此能够摆脱一个替换。原帖已更新
【解决方案2】:

如果业务担心客户无法正确处理datetime等复杂数据类型,想使用简单的int,至少使用标准的方式将日期存储为int

将日期存储为简单int 的一种广泛传播的方法是unix 时间。它始终是 UTC。它只是自 1970-01-01 以来经过的几秒钟。在任何情况下,您都应该使用bigint,而不是int。尽管如此,我还是会将数据库中的日期存储为datetime,并在与客户交谈时将其转换为unix时间。

从unix时间转换为日期时间:

DATEADD(second, [unixtime_value], '19700101')

从日期时间转换为 unix 时间:

DATEDIFF(second, '19700101', [datetime_value])

使用GETUTCDATE代替CURRENT_TIMESTAMP获取当前UTC时间,然后将其转换为bigint

DATEDIFF(second, '19700101', GETUTCDATE())

【讨论】:

  • 我的回复是反对你在原帖中的评论
猜你喜欢
  • 2010-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-08
  • 1970-01-01
  • 2022-08-23
相关资源
最近更新 更多