【问题标题】:Unable to understand how value converted to date format implicitly无法理解值如何隐式转换为日期格式
【发布时间】:2017-10-01 03:19:29
【问题描述】:

我检查了我的NLS_DATE_FORMATDD-MM-RR

考虑到带有日期列的 mytable,当我执行以下语句时,它会抛出错误“ORA-01840: input value not long enough for date format”,这是可以理解的。

insert into mytable values('10'); //Error: reason understandable

那么为什么在输入大小明显大于默认大小DATE Format 的情况下以下语句有效。

insert into mytable values('10AUGUST2016'); //reason not understandable

另外这里我没有使用任何TO_DATE 函数,我猜是隐式转换发生了?

【问题讨论】:

  • 是的 insert into mytable values('10'); 会抛出 ORA-01861: 错误,正如我所解释的,我理解其背后的原因。 insert into mytable values('10AUGUST2016'); 有什么错误吗?

标签: sql oracle date oracle11g


【解决方案1】:

String-to-Date Conversion Rules 允许附加格式规则(不应用任何其他修饰符)。所以:

  • MM 也匹配 MONMONTH
  • MON 匹配 MONTH(反之亦然);
  • RR 匹配 RRRR;和
  • 标点符号是可选的。

所以:

SELECT TO_DATE( '10AUGUST2016', 'DD-MM-RR'    ) FROM DUAL UNION ALL
SELECT TO_DATE( '10AUGUST2016', 'DD-MON-RR'   ) FROM DUAL UNION ALL
SELECT TO_DATE( '10AUGUST2016', 'DD-MONTH-RR' ) FROM DUAL UNION ALL
SELECT TO_DATE( '10AUG2016',    'DD-MM-RR'    ) FROM DUAL UNION ALL
SELECT TO_DATE( '10AUG2016',    'DD-MON-RR'   ) FROM DUAL UNION ALL
SELECT TO_DATE( '10AUG2016',    'DD-MONTH-RR' ) FROM DUAL;

全部生成日期2016-08-10T00:00:00

您可以使用FX format model 来防止这种情况发生

外汇

格式准确。此修饰符指定TO_DATE 函数的字符参数和日期时间格式模型的精确匹配:

  • 字符参数中的标点和引用文本必须与格式模型的相应部分完全匹配(大小写除外)。

  • 字符参数不能有多余的空格。如果没有FX,Oracle 会忽略多余的空格。

  • 字符参数中的数字数据必须与格式模型中的相应元素具有相同的位数。如果没有FX,字符参数中的数字可以省略前导零。

    启用FX 后,您也可以使用FM 修饰符禁用此前导零检查。

如果字符参数的任何部分违反了这些条件中的任何一个,那么 Oracle 将返回一条错误消息。

然后:

SELECT TO_DATE( '10-AUGUST-2016', 'FXDD-MM-RR'    ) FROM DUAL;

给出:ORA-01858: a non-numeric character was found where a numeric was expected,并且只匹配找到精确模式匹配的位置(尽管RR 仍将匹配RRRR)。

我猜隐式转换正在发生?

是的,oracle 隐式使用TO_DATE( '10AUGUST2016', NLS_DATE_FORMAT ) 进行转换。

如果你使用:

ALTER SESSION SET NLS_DATE_FORMAT = 'FXDD-MM-RR';

那么你的插入将失败。

【讨论】:

  • 格式替换显示为later in the same doc(或12cR2 version,其中有一个关于标点字符的额外项目符号)。
  • @AlexPoole 谢谢,我已经扫描了该文档,但没有发现它。我假设在我到达倒数第二部分之前我的大脑已经融化了。现在更新以指向您引用的部分。
  • @MT0 我认为即使使用FX,RR 也无法匹配 RRRR。正如我所见,select to_date('20-04-2017','fxdd-mm-rr') from dual 失败 ORA-01830。
猜你喜欢
  • 2013-07-09
  • 2014-02-25
  • 2018-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-12
  • 1970-01-01
相关资源
最近更新 更多