今天,我发现Oracle NLS_NUMERIC_CHARACTERS
的定义不明确!
确实,从一开始,我就认为NLS_NUMERIC_CHARACTERS
仅用于定义十进制数字的显示方式。
但实际上,NLS_NUMERIC_CHARACTERS
函数中还隐式使用了TO_NUMBER()
来定义要转换的STRING编号的格式。
我的问题是我是欧洲人,对我来说,十进制分隔符实际上是逗号(,),而不是点(.)。
当我显示一个数字时,我的偏好是使用逗号显示它。因此,NLS_NUMERIC_CHARACTERS
设置为',.'
,其中第一个字符定义数字分隔符。
到目前为止,我对此没有任何问题:-)
我的问题是,包含数字的所有String
表字段的值都使用POINT字符作为小数点分隔符。
当我将任何表示数字的字符串值转换时,可以使用TO_NUMBER Oracle函数,如下所示
select TO_NUMBER(VALUE) from TB_PARAMETER;
如果小数点分隔符为POINT(
NLS_NUMERIC_CHARACTERS = '.,'
),则此方法效果很好,但如果小数点分隔符为COMMA(NLS_NUMERIC_CHARACTERS = ',.'
),则此方法停止工作。我知道我可以像这样在
NLS_NUMERIC_CHARACTERS
函数中指定TO_NUMBER()
select TO_NUMBER(VALUE
,'999999999D999999999'
,'NLS_NUMERIC_CHARACTERS = ''.,'''
)
from TB_PARAMETER;
但这对我来说很冗长!
是否有执行相同功能的Oracle函数?
例:
select CAST_NUMBER(VALUE) from TB_PARAMETER;
从个人角度来说,我认为Oracle
TO_NUMBER()
函数使用NLS_NUMERIC_CHARACTERS
session 的参数来定义要转换的十进制字符串格式的事实是错误。实际上,在数据库中,字符串中使用的十进制分隔符始终是固定的。它是逗号或一点,但绝不是逗号,一次是点。
如果我的分析是正确的,则
TO_NUMBER()
函数必须始终使用一个固定值,即POINT或COMMA(在所有情况下均不与NLS_NUMERIC_CHARACTERS对应),因为此参数具有 session 范围,并且由Oracle客户端应用程序定义。在简历中,当您在Oracle View 中使用
TO_NUMBER()
函数而不指定任何NLS_NUMERIC_CHARACTERS
时,您的 View 将正确运行,直到在具有另一个NLS_NUMERIC_CHARACTERS
值的 session 中执行该 View 为止!当您尝试使用Oracle
TO_DATE()
函数转换保存为字符串的DATE值时,肯定存在同样的事情!为什么模棱两可!
为了回答评论中的一些问题,我在以下段落中添加了我的详细解释。
由于NLS_NUMERIC_CHARACTERS具有两个不同的角色或目标,因此在 session 级别或系统级别更改NLS_NUMERIC_CHARACTERS并不总是可能的。
函数
示例:假设您将创建一个显示十进制数字并使用TO_NUMBER()进行计算的 View 。
如果保存在数据库中的小数点分隔符是POINT,并且有必要使用COMMA作为小数点分隔符显示小数点,则可以更改NLS_NUMERIC_CHARACTERS以将小数点分隔符定义为POINT。 Oracle TO_NUMBER()函数将正确运行,但屏幕上显示的小数将以POINT作为小数分隔符显示!
这就是为什么我说NLS_NUMERIC_CHARACTERS不明确。
在简历中,在数据库系统中NLS_NUMERIC_CHARACTERS可以为“。”或“。”。 AND,可以使用固定的格式将十进制数保存在Oracle表中(例如:十进制分隔符为POINT),使用TO_NUMBER()而不指定正确的NLS_NUMERIC_CHARACTERS是不安全的。
Oracle错误(或者您可能会误解)是定义了具有2个不同角色的参数(NLS_NUMERIC_CHARACTERS)!
最佳答案
从我的角度来看,最好的选择是将数字保留在NUMBER
数据类型列中。您如何将TO_NUMBER
应用于value = '32.5rzg'
?
除此之外,我假设您已经发现(应用NLS_NUMERIC_CHARACTERS
)是可以做的,除了使用REPLACE
并将所有点转换为整个字符串值中的逗号之外。
关于oracle - 考虑到在数据库服务器上定义的NLS_NUMERIC_CHARACTERS,如何使用正确的TO_NUMBER()Oracle函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51962063/