我正在看一些SQL并试图了解它正在尝试做什么.我被告知它在昨天午夜和今天之间返回数据.有人可以将以下摘录翻译成简单的英语吗?
SELECT ...
FROM ...
WHERE CREATEDATE >=TO_DATE(TRUNC(SYSDATE-1) || ' 00:00:00', 'DD-MON-YY HH24:MI:SS')
AND CREATEDATE <=TO_DATE(TRUNC(SYSDATE-1) || ' 23:59:59', 'DD-MON-YY HH24:MI:SS')
Run Code Online (Sandbox Code Playgroud)
除非我将底线改为:否则这似乎不起作用:
AND CREATEDATE <=TO_DATE(TRUNC(SYSDATE) || ' 23:59:59', 'DD-MON-YY HH24:MI:SS')
Run Code Online (Sandbox Code Playgroud)
任何帮助理解此代码将不胜感激.
谓词看起来比它们需要的更复杂.
为什么这不会返回您想要返回的结果?
WHERE CREATEDATE >= TRUNC(SYSDATE-1)
AND CREATEDATE < TRUNC(SYSDATE)
Run Code Online (Sandbox Code Playgroud)
要在"普通英语"中解释这个SELECT语句返回的所有三个表达式:
SELECT SYSDATE
, TRUNC(SYSDATE)
, TRUNC(SYSDATE-1)
FROM DUAL
Run Code Online (Sandbox Code Playgroud)
返回DATE值(Oracle数据类型为DATE的值).
------------------- ------------------- -------------------
2016-04-16 13:59:26 2016-04-16 00:00:00 2016-04-15 00:00:00
Run Code Online (Sandbox Code Playgroud)
我们没有看到的是CREATEDATE的数据类型.显然,我们希望将其定义为DATE.但是如果你已经将它声明为VARCHAR并且以'16 -APR-2016 13:59:26'的格式存储字符串,那么"似乎不起作用",除非"你观察到的问题只是冰山一角.
(如果将CREATEDATE声明为VARCHAR而不是DATE,则可以很容易地解释您正在观察的行为.)
如果您的SQL 在写入时正在工作,则它取决于NLS_DATE_FORMAT的当前设置.也就是说,您的SQL可以通过相对无害的语句轻松破解,例如:
ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD' ;
Run Code Online (Sandbox Code Playgroud)
您当前查询中表达式的某些组件的概述......
SYSDATE 将当前日期和时间作为DATE返回
SYSDATE-1 从当前日期和时间减去1天并返回DATE
TRUNC(<dateexpr>) 从DATE值"关闭"时间组件,仅返回时间设置为午夜的日期部分
|| 是字符串连接运算符
(注意:使用DATE表达式执行字符串连接需要Oracle执行隐式TO_CHAR转换.Oracle使用NLS_DATE_FORMAT作为默认格式模型.)
' 单引号括起字符串文字该TO_DATE函数的第二个参数是格式模型.
DD 是两位数的日子(例如07或16)MON 是本月的三个字母缩写YY 是一年的两个字符代表,隐含的世纪(HH24 是两位数小时(24小时制),00至23 MI 是两位数的分钟,00到59SS 是两位数秒,00到59(注意:我们不是已经解决了Y2K问题吗?为什么要重新创建它?)
我认为最重要的事情要了解当前的SQL:它使用的表达式比需要的更复杂.我认为这些表达方式有三种方式:
依赖于NLS_DATE_FORMAT的隐式TO_CHAR函数来适当匹配TO_DATE函数中的显式格式模型
没有理由使用两个字符的年份,我们可以轻松使用四位数年份.特别是当首先不需要将DATE值转换为字符串时.
使用<=比较而不是<比较,取决于日期时间类型的最大精度为1秒,当我们可以轻松指定"小于"第二天的午夜时,使用处理小数秒的模式.
如果CREATEDATE被声明为VARCHAR,那么它会以另一种方式被破坏......比较将作为字符串比较执行.对于比较右侧的表达式,存在隐式TO_CHAR转换.这些转换(再次)依赖于NLS_DATE_FORMAT设置.使用古老的Oracle默认设置DD-MON-YY,字符串比较将在某种意义上起作用,即它不是无效的语法,但就返回两个其他日期值之间的日期值而言,这些比较会被破坏.