SQL命令未给出预期结果。
UPDATE table SET DATE_COL=trim(DATE_COL).
未生成错误消息。
我错误地使用TRIM()删除Oracle表中日期类型列上的空间。结果如下:如果日期在(30.12.1899-31.12.1949)之间,则将100年添加到结果中。如果范围是(1.1.1950 - 31.12.2049),则将100年减去。如果范围是1.1.1950-31.12.2049,则结果不会改变。当然,它根本不应该用于日期类型。
警告在错误的对象上使用trim()
2条答案
按热度按时间hrysbysz1#
如果您这样做:
那么你实际上是在做:
这与以下内容相同:
如果你的
NLS_DATE_FORMAT
是YYYY-MM-DD HH24:MI:SS
,那么你的约会不会发生任何事情。但是如果
NLS_DATE_FORMAT
是DD-MON-RR
,那么日期1920-01-01T12:34:56
将被转换为01-JAN-20
,然后转换回日期2020-01-01T00:00:00
,这将改变世纪(因为RR
模型将20
解释为当前世纪2020
)并将时间分量截断为午夜。最简单的解决方案是使用
ROLLBACK
将数据库恢复到最近的提交。如果您已经提交了,则需要从最近的备份中恢复表。ws51t4hk2#
这种行为可能不是你想要或期望的,但它是文档中所说的会发生的。The trim function说:
trim_character和trim_source都可以是VARCHAR 2或任何可以隐式转换为VARCHAR 2的数据类型。
和日期可以隐式地转换为字符串,反之亦然。
当你执行
trim(DATE_COL)
时,日期值被隐式转换为字符串,就像你执行trim(to_char(DATE_COL))
一样,这将使用你的NLS设置,特别是NLS_DATE_FORMAT。从你所看到的来看,你似乎将其设置为'DD-MON-RR'。因此,例如1899-12-31被格式化为字符串'31-DEC-99'。然后该字符串值被修剪,请注意,如果原始日期具有非午夜时间,则该时间现在也已丢失。然后,当你用
DATE_COL=trim(DATE_COL)
将该值赋回日期列时,它会隐式地转换回来,实际上是DATE_COL=to_date(trim(to_char(DATE_COL)))
。to_date()
再次使用了你的NLS设置,所以对于那个示例日期,你现在是在做DATE_COL=to_date('31-DEC-99')
。因为它也使用了NLS_DATE_FORMAT,所以它实际上是to_date('31-DEC-99', 'DD-MON-RR')
,RR格式元素行为表明它将被解释为1999。您可以看到日期范围in this fiddle发生了什么,中间字符串值以及如何将其转换回日期。
| 旧完整日期|旧STR|新日期|新完整日期|
| --------------|--------------|--------------|--------------|
| 1849-12-31 23:59:59|一九四九年十二月三十一日|一九四九年十二月三十一日|2049-12-31 00:00:00|
| 1850年1月1日00时00分|2050年1月1日|2050年1月1日|1950-01-01 00:00:00|
| 2019 - 09 -12 00:00:00|一九九九年十二月三十一日|一九九九年十二月三十一日|一九九九年十二月三十一日上午十时|
| 1900年1月1日00时00分|2000年1月1日|2000年1月1日|二○ ○ ○年一月一日上午十时|
| 1949-12-31 00:00:00|一九四九年十二月三十一日|一九四九年十二月三十一日|2049-12-31 00:00:00|
| 1950-01-01 00:00:00|2050年1月1日|2050年1月1日|1950-01-01 00:00:00|
| 一九九九年十二月三十一日上午十时|一九九九年十二月三十一日|一九九九年十二月三十一日|一九九九年十二月三十一日上午十时|
| 二○ ○ ○年一月一日上午十时|2000年1月1日|2000年1月1日|二○ ○ ○年一月一日上午十时|
| 2049-12-31 00:00:00|一九四九年十二月三十一日|一九四九年十二月三十一日|2049-12-31 00:00:00|
| 2019 -01- 12 00:00:00|2050年1月1日|2050年1月1日|1950-01-01 00:00:00|
| 二○九九年十二月三十一日零时|一九九九年十二月三十一日|一九九九年十二月三十一日|一九九九年十二月三十一日上午十时|
这个小提琴还显示,如果NLS_DATE_FORMAT中有一个4位数的年份,你会保留世纪(但仍然截断时间)。这并不是说你应该依赖隐式转换或NLS设置,它只是演示效果。
很不幸,它在做你让它做的事。
数据库无法猜测你要做什么--它只知道你告诉它做什么--或者你什么时候做了,而不是打算依赖隐式转换。编码人员有责任使用适当的函数来实现他们想要实现的目标。