我有一个直接使用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。参数的值是DateTime,其类型也指定为UTC。
更新: 该问题似乎与我从IDataRecord设置的结果有关。当我关闭DateTimes时,我使用DateTime.SpecifyKind()将它们置于UTC模式。问题是,日期时间是DateTimeKind.Unspecified。从Unspecified转换为UTC时,它只删除时区并声明它是UTC而不更改基础值。我不确定如何让IDataRecord拉入TimeZone值。
答案 0 :(得分:3)
您需要使用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');
答案 1 :(得分:0)