您要么依赖隐式日期转换,要么依赖隐式格式模型;既然你说你正在使用to_date
它to_timestamp
似乎是后者。您尚未显示您的代码,但错误意味着您正在使用您希望看到的格式的字符串值调用这些函数,但没有明确提供格式模型作为函数的第二个参数。这将导致使用会话的 NLS_DATE_FORMAT 设置。如果你这样做:
to_date('12/06/2015 09:10:11')
那么你真的在有效地做:
to_date('12/06/2015 09:10:11', (select value from nls_session_parameters where parameter = 'NLS_DATE_FORMAT'))
您无法控制您的客户将如何配置他们的 NLS 环境,因此您永远不应依赖隐式转换或 NLS 假设。
正如文档中所说:
注意:
最好始终使用 TO_DATE 指定格式掩码 (fmt),如以下部分中的示例所示。当它不带格式掩码使用时,仅当 char 使用与 NLS_TERRITORY 或 NLS_DATE_FORMAT 参数确定的相同格式时,该函数才有效。此外,除非指定显式格式掩码以避免依赖关系,否则该函数可能在数据库之间不稳定。
你可以看到这如何影响一个简单的查询:
SQL> alter session set nls_date_format = 'DD/MM/YYYY HH24:MI:SS';
Session altered.
SQL> select to_date('12/06/2015 09:10:11') from dual;
TO_DATE('12/06/2015
-------------------
12/06/2015 09:10:11
SQL> alter session set nls_date_format = 'DD/MM/YYYY';
Session altered.
SQL> select to_date('12/06/2015 09:10:11') from dual;
select to_date('12/06/2015 09:10:11') from dual
*
ERROR at line 1:
ORA-01830: date format picture ends before converting entire input string
出于同样的原因,您应该避免使用月份名称,因为它们的解释取决于 NLS_DATE_LANGUAGE;虽然如果你真的需要的话,你至少可以在查询级别覆盖它。
如果您使用固定值,您可能还需要考虑日期和时间戳文字:
select date '2015-06-12' ...
select timestamp '2015-06-12 09:10:11' ...
但是,如果您正在构建要转换为日期的字符串,那么这将是不合适的。