1

我刚刚查看了 OCA 认证问题,我意识到有些地方是不正确的。他们问:

请按升序提供所有用户的录用时间(HR 用户)

所以我写了下一个查询:

SELECT employee_id, first_name, last_name, hire_date
  FROM employees 
 WHERE hire_date BETWEEN '01/01/80' AND '01/01/99'
 ORDER BY hire_date;

并且指导说这是不正确的,因为该数据时间不正确!那应该是'01-JAN-80'。什么?这难以置信!

我的笔记本电脑上没有安装数据库,但我确信我在上次工作中多次运行此查询,并且数据格式/-.

欢迎任何建议。

更新

我刚刚在 xe 10g 中对其进行了测试,并且绝对/不是-

http://imageshack.us/photo/my-images/28/truethat.jpg/ ()

4

2 回答 2

4

你和你的导师都不对。你们中的任何一个都可能碰巧偶尔是正确的。

如果将日期与字符串进行比较,Oracle 必须将字符串转换为日期。为了做到这一点,它使用会话的当前NLS_DATE_FORMAT. 不同的客户会有不同的默认值NLS_DATE_FORMAT——不同的地区使用不同的默认格式,不同的人会喜欢不同的格式。如果您依赖隐式转换,那么只要会话NLS_DATE_FORMAT不符合您的期望,您的代码就会失败。而且,不可避免地,这意味着代码将在最不合时宜的时刻失败。

不应将日期与字符串进行比较,而应始终将日期与日期进行比较。在 Oracle 中有两种方法可以做到这一点。首先,您可以使用TO_DATE具有适当格式字符串的显式,即

SELECT employee_id, first_name, last_name, hire_date
  FROM employees 
 WHERE hire_date BETWEEN to_date('01/01/80','mm/dd/rr') AND to_date('01/01/99','mm/dd/rr')
 ORDER BY hire_date;

其次,您可以使用 ANSI 日期文字。ANSI 日期文字始终使用格式YYYY-MM-DD

SELECT employee_id, first_name, last_name, hire_date
  FROM employees 
 WHERE hire_date BETWEEN date '1980-01-01' AND date '1999-01-01'
 ORDER BY hire_date;
于 2012-04-16T02:12:39.423 回答
3

就个人而言,我不依赖隐式转换。这往往会导致未来的意外悲伤。如果要求在日期范围之间提供过滤器,我会很明确。选择您想要的任何格式,但如果它可能会造成混淆,请尝试尽可能多地消除混淆:

SELECT employee_id, first_name, last_name, hire_date
  FROM employees 
  WHERE hire_date BETWEEN TO_DATE('JAN-01-1980', 'MON-DD-YYYY')
                      AND TO_DATE('JAN-01-1999', 'MON-DD-YYYY')
  ORDER BY hire_date;
于 2012-04-16T00:53:12.347 回答