Firebird 2.5中timestamp与字符串日期比较及更新不生效问题
Firebird 2.5 timestamp类型与字符串日期比较方案
语句未命中记录的核心原因:Firebird 2.5的TIMESTAMP类型默认支持亚秒级精度(最高到万分之一秒),多数数据库客户端展示timestamp值时会默认截断到秒级,你肉眼看到记录值是2022-06-08 11:26:45,实际存储值大概率带未展示的小数秒部分(比如2022-06-08 11:26:45.0782)。你写的语句中CAST('2022-06-08 11:26:45' AS TIMESTAMP)会把缺失的小数秒置为0,自然无法和带小数秒的实际存储值匹配。
以下是三种可落地的正确比较方式,按需选择即可:
截断到秒级精确匹配(适配绝大多数场景)
把字段值和比较值都统一截断到秒级精度再做等号匹配,忽略亚秒部分的差异:UPDATE inventario_setor SET data_fechamento = NULL WHERE CAST(DATA_FECHAMENTO AS TIMESTAMP(0)) = CAST('2022-06-08 11:26:45' AS TIMESTAMP(0))语法中
TIMESTAMP(0)代表保留0位小数,即精度到秒。时间范围匹配(性能最优,支持索引命中)
如果data_fechamento字段建有索引,不要在字段上套函数,用区间查询圈定目标时间所在的1秒范围即可,查询效率远高于字段加函数的写法:UPDATE inventario_setor SET data_fechamento = NULL WHERE DATA_FECHAMENTO >= CAST('2022-06-08 11:26:45' AS TIMESTAMP) AND DATA_FECHAMENTO < CAST('2022-06-08 11:26:46' AS TIMESTAMP)亚秒级精确匹配
如果确实需要精确匹配到亚秒级,必须在比较字符串中补全实际存储的完整小数秒部分,再做等号比较:-- 假设实际存储值带0.0782的小数秒 UPDATE inventario_setor SET data_fechamento = NULL WHERE DATA_FECHAMENTO = CAST('2022-06-08 11:26:45.0782' AS TIMESTAMP)
注意:写时间字符串时请始终使用
YYYY-MM-DD HH:MI:SS[.ffff]的ISO标准格式,避免因数据库服务端的区域日期配置差异,导致字符串转timestamp时出现解析错误。
内容的提问来源于stack exchange,提问作者Diego Alves
相关产品推荐
相关产品推荐

