【问题标题】:Oracle DateTime query with time zones带有时区的 Oracle DateTime 查询
【发布时间】:2012-02-06 21:54:12
【问题描述】:

我有一个直接使用 ADO.NET 的 SQL Builder 库。我有一种方法可以使用大于或等于运算符创建选择查询,例如:

select *
from book
where book.date_created >= {some date}

我的问题是 {some date} 将始终处于 UTC 时区,但它与 book.date_created 列进行比较,该列是 TIMESTAMP(6) WITH TIME ZONE 列,不会在UTC 时区。

我可以执行查询,但我的结果与时区比较不同。我的查询是针对 date_created >= x 的所有书籍,但返回的某些结果不大于 x,因为在减去时区 5 小时后,它们现在小于 x。返回的 IDataRecord DateTime 字段使用 DateTime.SpecifyKind() 转换为 UTC

我可以形成我的查询,使其解释 UTC 时区中的 book.date_created 吗?

注意:虽然我很想将我的 Oracle DB 列更改为不指定时区,但我无法更改表结构。

编辑: 目前,{some date} 是一个 SQL 参数。它的支持数据类型是以 UTC 作为时区的 DateTime。作为参数,它是 TimestampWithTZ。该参数的值是一个日期时间,其类型也指定为 UTC。

更新: 这个问题似乎与我在 IDataRecord 中的结果集有关。当我关闭 DateTimes 时,我使用 DateTime.SpecifyKind() 将它们置于 UTC 模式。问题是,日期时间显示为 DateTimeKind.Unspecified。从 Unspecified 转换为 UTC 时,它只是删除时区并声明它是 UTC 而不会更改基础值。我不确定如何让 IDataRecord 拉入 TimeZone 值。

【问题讨论】:

  • “某个日期”变量是否定义为日期、时间戳或带时区的时间戳?你能展示一些使用的.net代码吗?
  • 我假设您正在使用 Oracle 的增强型 ado.net(odp.net 或 ODAC),并为“某个日期”使用 OracleTimeStampTZ 结构,对吗?问题可能不在于您如何存储时间戳,而在于您在 .NET 方面将其与什么进行比较(这就是我要求一些 .NET 代码的原因)。
  • 我使用的是普通的 ADO.NET。我认为问题可能不在于比较,而是由于某种原因,IDataRecord 的 DateTime 类型值未指定。

标签: sql oracle ado.net timezone


【解决方案1】:

您需要使用 FROM_TZ 函数将 TIMESTAMP 转换为 TIMESTAMP WITH TIME ZONE。例如,如果您知道您的变量是 UTC 时间 (+0:00):

SELECT * 
  FROM book 
 WHERE date_created >= from_tz(<timestamp>, '+0:00');

这是一个示例脚本,显示您描述的行为(您的本地时区应设置为+1:00):

CREATE TABLE t (tz TIMESTAMP(6) WITH TIME ZONE);
INSERT INTO t VALUES 
(to_timestamp_tz('20000101 00:00:00 +1:00','yyyymmdd hh24:mi:ss tzh:tzm'));
INSERT INTO t VALUES 
(to_timestamp_tz('20000101 00:00:00 -1:00','yyyymmdd hh24:mi:ss tzh:tzm'));

-- This will return two values instead of one
SELECT * 
  FROM t 
 WHERE tz >= to_timestamp('20000101 00:00:00', 'yyyymmdd hh24:mi:ss');

-- This query will return only one row
SELECT * 
  FROM t 
 WHERE tz >= from_tz (to_timestamp('20000101 00:00:00', 
                                   'yyyymmdd hh24:mi:ss'), '+0:00');

【讨论】:

  • 文森特,看看我的编辑。看起来 Oracle 参数的 Oracle 类型已经为 TimestampWithTZ。
  • 也可以使用 from_tz(..., 'UTC') (而不是 from_tz(..., '+0:00'))。
【解决方案2】:
猜你喜欢
  • 2017-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-06
  • 2014-08-07
  • 2015-05-20
  • 2011-11-12
  • 1970-01-01
相关资源
最近更新 更多