我正在尝试基于列进行比较。比方说,如果列> 5。
select * where column>5
该列包含非数字。我认为 Oracle 允许比较字符串(如 Java)。
显然这是不允许的。
ORA-01722: invalid number
01722. 00000 - "invalid number"
有没有办法与非数字字段进行比较?
谢谢
是的,您必须将 5 放在引号中:
select * from table where column > '5'
如果列是varchar2
,那么:
select * from some_table where some_column > 5
... 将所有列值隐式转换为数字,所以你真的在做:
select * from some_table where to_number(some_column) > 5
这是to_number()
导致 ORA-01722 的原因,即使您看不到它,但当它遇到一个非数字值时。对列值调用的函数也会停止使用任何索引(有点过于简单化了)。
您可以阻止它失败,如果有索引,则让它使用索引,where some_column > '5'
就像其他人所说的那样,或者where some_column > to_char(5)
. 但是您需要小心进行比较,因为它仍然是字符串比较,而不是数字比较;所以'10'
不会被视为> '5'
;并且您的 NLS 排序参数可能会产生您不期望的结果。或者更重要的是,其他人的 NLS 参数(例如,当您将其上线时)可能会产生您不期望的结果,并且与您在环境中获得的结果不匹配。有关更多信息,请参阅文档。
您应该使用number
列来保存数值,使用date
列来保存日期等,并且varchar2
只保存文本值。
更清楚地说明它为什么不起作用。
当使用数字文字5
而不是字符文字时,'5'
Oracle 会进行隐式数据类型转换并尝试将表中的所有值转换为数字。这就是为什么你得到那个错误。
您永远不应该依赖隐式数据类型转换。这一定会给你带来麻烦。
现在,如果您正确地将字符文字 ( '5'
) 与字符列进行比较,则无需进行数据类型转换,也不会发生错误。
但是:如果您希望 Oracle 实际进行数字比较,那么您就错了。字符串基于 ASCII 值。因此(字符)值'10'
低于(字符)值'2
' 因为第一个字符'1'
的排名低于'2'
。
你可以使用to_char
功能
select * from table where column > to_char(5)