【问题标题】:Convert() SQL Server to OracleConvert() SQL Server 到 Oracle
【发布时间】:2021-05-20 02:11:38
【问题描述】:

我在 SQL Server 上有这个查询,这个查询的目标是设置毫秒为 000,例如,

在此查询之前:2017-06-01 11:53:00.123
之后:2017-06-01 11:53:00.000

UPDATE table1 
  SET ValidFrom = CONVERT(DATETIME, CONVERT(CHAR(19), ValidFrom, 126)) 
WHERE ValidFrom IS NOT NULL;

ValidFrom 是数据库上的一个列,它是一个日期时间。

Oracle 上有一个转换命令,但它不适用于日期时间。

如何将其翻译到 Oracle?

【问题讨论】:

  • 您需要解释该表达式的作用——不是每个了解 Oracle 的人都知道 convert() 做什么或 126 应该做什么。 Oracle 中也没有datetime 数据类型。您可能正在寻找timestamp
  • 1º 这是一个删除毫秒的查询,此查询之前:2017-06-01 11:53:00.123 之后:2017-06-01 11:53:00.000。 2º 126 是 convert 方法中的可选参数,表示它必须转换的日期时间类型 (yyyy-mm-ddThh:mi:ss.mmm)
  • @CMorillo 为什么要删除毫秒?
  • 名称 ValidFrom 通常用于临时表(与临时表无关,顺便说一句)- 如果这是一个临时表,那么您不应该修改 ValidFromValidTo完全(事实上我认为你甚至可以因为SQL Server会阻止写入)。
  • 您使用的是什么版本的 Oracle 数据库?

标签: sql oracle timestamp


【解决方案1】:
  • 将任何强类型的datedatetimedatetimeoffset 等列转换为char/varchar 是一种代码味道,并且强烈暗示你做错了什么,因为你永远不应该需要格式化日期以在 SQL 中执行日期/时间处理。
  • Oracle 没有像 SQL Server 那样的 datetime 类型,而是有一个 timestamp 类型(这与 SQL Server 自己的 timestamp 类型完全无关,它是 rowversion 的别名,但是我跑题了)。
  • Oracle 的 timestamp 类型已参数化以指定亚秒级分辨率的精度 - 因此只需将您的值 CAST 设置为 timestamp(0) 即可有效地将毫秒部分归零。
  • 您还可以使用EXTRACT 函数获取timestamp 值的毫秒部分的整数值(0-999)。
UPDATE
    table
SET
    ValidFrom = CAST( ValidFrom AS timestamp(0) )
WHERE
    ValidFrom IS NOT NULL

Here's a working demo in SQLFiddle, using Oracle 11g R2:

构建架构脚本:

CREATE TABLE testTable (
    ValidFrom timestamp(7) NOT NULL
);

INSERT INTO testTable ( ValidFrom )
WITH v AS ( 
    SELECT TIMESTAMP '1997-01-08 11:11:11.111' AS ts FROM dual UNION ALL 
    SELECT TIMESTAMP '1997-02-09 12:22:22.222' AS ts FROM dual UNION ALL 
    SELECT TIMESTAMP '1997-03-10 13:33:33.333' AS ts FROM dual UNION ALL 
    SELECT TIMESTAMP '1997-04-11 14:44:44.444' AS ts FROM dual
) 
SELECT ts FROM v

查询脚本:

SELECT
  ValidFrom,
  CAST( ValidFrom AS timestamp(0) ) AS ValidFrom_withoutMilliseconds,
  ( ValidFrom - CAST( ValidFrom AS timestamp(0) ) ) AS diff
FROM
  testTable

//

UPDATE
    testTable
SET
    ValidFrom = CAST( ValidFrom AS timestamp(0) )
WHERE
    ValidFrom IS NOT NULL

//

SELECT
  ValidFrom,
  CAST( ValidFrom AS timestamp(0) ) AS ValidFrom_withoutMilliseconds,
  ( ValidFrom - CAST( ValidFrom AS timestamp(0) ) ) AS diff
FROM
  testTable
  • 今天了解到//是查询分隔符,与Oracle中的“查询终止符”是分开的。
  • 令我惊讶的是,Oracle 数据库仍然不支持EXTRACT 的毫秒数,幸运的是,此查询不需要。

【讨论】:

  • 此查询不起作用,因为您正在删除毫秒,而我不想删除它们,我想将其值更改为 .000
  • @CMorillo 你有没有试过我的查询?
  • @CMorillo 它应该可以工作,因为虽然从timestamp(n)timestamp(0) 有一个明确的缩小转换(这将删除毫秒值),但请注意@987654344 @ 将调用 隐式转换 回到列的 timestamp(n) 类型,这将导致毫秒组件归零,与将 date 值转换为 datetimetimestamp 的方式相同value 将导致小时、分钟和秒组件清零。
  • 我尝试了您的查询,但出现错误:“缺少关键字”。我认为 CAST 命令有问题
  • @CMorillo 我已经更新了我的答案。它只需要AS 而不是,
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-21
  • 2011-05-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多