到目前为止,Oracle隐式转换字符串?

时间:2016-01-11 15:18:32

标签: sql oracle plsql

我在T-SQL工作,但已获得一些Oracle PL-SQL供项目审核。

在代码中有多个WHERE子句,它们将DataType = DATE字段与保存" date"的字符串进行比较。

前:

       WHERE to_date(mytable.mydatefield) > '23-OCT-2015'

OR

       WHERE mytable.mydatefield > '23-OCT-2015'

Q1:因为" mydatefield"已被定义为DATA类型,并未进行" to_date"不必要?

第二季度:甲骨文将在' 23-OCT-2015'上进行隐式转换。并将其转换为比较日期?我似乎记得在此之前遇到过这种情况并将DATES与STRINGS比较造成问题? 我错了吗?如果没有,有人可以给我一个例子,我可以作为证据证明它不起作用吗?

2 个答案:

答案 0 :(得分:3)

A1:一般情况下是,但请考虑Oracle处理隐式类型转换的方式。 To_Date列周围的mydatefield函数需要输入字符串,因此Oracle隐式地将mydatefield转换为格式与NLS_DATE_FORMAT会话设置匹配的字符串(默认为DD- MON-RR)。转换为字符串后,To_Date函数会使用当前的NLS_DATE_FORMAT设置将其转换回日期。然后将新重构的日期与字符串'23 -OCT-2015'进行比较,但由于日期和字符串不能直接比较,因此使用当前NLS_DATE_FORMAT设置将字符串值隐式转换为日期。根据{{​​1}}设置的值,第一次隐式转换可能会丢失特定于任何时间部分和原始世纪的信息,因为默认NLS_DATE_FORMAT仅使用两位数的年份NLS_DATE_FORMAT没有时间成分。

A2:可能,但最好不要依赖它。

由于几个原因,这两种关系都很糟糕。首先,它们都受到从日期到字符串的隐式类型转换的影响(反之亦然)。其次,他们都试图用非规范形式比较日期和字符串。因此,10-DEC-15小于23-OCT-2015,因为1小于2.另请注意,自默认RR使用两位数年以来,代表年份的位数差异。

正确的方法是将日期列(可能是截断的)与显式转换为日期的日期字符串进行比较

NLS_DATE_FORMAT

OR与截断:

WHERE mytable.mydatefield > TO_DATE('23-OCT-2015', 'DD-MON-YYYY')

删除日期字段的时间部分。

答案 1 :(得分:0)

Q1:根据Oracle,to_date()的第一个参数是char值。像to_date(date_value)一样使用它会强制将date_value隐式转换为char,然后将其再次包装在日期值中。

Q2:服务器将从字符串' 23-OCT-2015'进行隐式转换。到日期值但是基于数据库参数可能与各种服务器不同(例如DEV与PROD),所以你不应该依赖它们。正确使用的示例是WHERE mytable.mydatefield > to_date('23-OCT-2015','dd-MON-yyyy')

您应始终使用to_date / to_char以确保使用正确的格式。请参阅此答案以获取更详细的说明:Comparing Dates in Oracle SQL