PLSQL错误:无效数字
我正在尝试执行此查询,它是我的过程的一部分,也是产生问题的一部分:PLSQL错误:无效数字,sql,oracle,Sql,Oracle,我正在尝试执行此查询,它是我的过程的一部分,也是产生问题的一部分: select SUM( CASE --DT007 WHEN PRO.Sens_Mnt_Brut = 'D' THEN '-' || TO_CHAR(PRO.Mnt_Brut,'99999999999,99') WHEN PRO.Sens_Mnt_Brut = 'C' THEN '' |
select SUM(
CASE --DT007
WHEN PRO.Sens_Mnt_Brut = 'D'
THEN '-' || TO_CHAR(PRO.Mnt_Brut,'99999999999,99')
WHEN PRO.Sens_Mnt_Brut = 'C'
THEN '' || TO_CHAR(PRO.Mnt_Brut,'99999999999,99')
END) OVER(PARTITION BY PRO.Num_Est_Remise) - SUM(TO_CHAR(PRO.Mnt_Comm_Tot_Ope,'99999999999,99')) OVER(PARTITION BY PRO.Num_Est_Remise))--DT015
From dlc_pr_operation pro;
执行后,我收到以下错误:
ORA-01722: invalid number
01722. 00000 - "invalid number"
*Cause:
*Action:
这是因为我在查询中添加了从char到number和逗号的转换,还是因为其他原因
提前感谢您的帮助。您正在进行大量数字和字符串之间的显式和隐式转换,不一致性和假设让您感到困惑。但无论如何,它们都是不必要的——您根本不需要在字符串之间进行转换。您的查询可以重写为:
select SUM(
CASE PRO.Sens_Mnt_Brut WHEN 'D' THEN -1 ELSE 1 END * PRO.Mnt_Brut
) OVER (PARTITION BY PRO.Num_Est_Remise)
- SUM(PRO.Mnt_Comm_Tot_Ope) OVER(PARTITION BY PRO.Num_Est_Remise)
From dlc_pr_operation pro;
它只是根据Sens_Mnt_Brut
标志决定Mnt_Brut
是应按原样使用还是应取反,并将其乘以1或-1(视情况而定)
您的方法至少有两个问题。您使用显式格式模型将数字转换为字符串,然后隐式地将它们转换回数字以求和;这意味着(a)隐式转换依赖于NLS设置,以及(b)使用显式模型无法将正在生成的字符串转换回 让我们从一些将进入第一个分支的虚拟数据开始:
with dlc_pr_operation (Sens_Mnt_Brut, Mnt_Brut, Mnt_Comm_Tot_Ope, Num_Est_Remise) as (
select 'D', 1234.56, 1, 2 from dual
)
select to_number('-' || TO_CHAR(PRO.Mnt_Brut,'99999999999,99')) from dlc_pr_operation pro;
ORA-01722: invalid number
如果你看它形成的绳子,你会看到:
with dlc_pr_operation (Sens_Mnt_Brut, Mnt_Brut, Mnt_Comm_Tot_Ope, Num_Est_Remise) as (
select 'D', 1234.56, 1, 2 from dual
)
select '-' || TO_CHAR(PRO.Mnt_Brut,'99999999999,99') from dlc_pr_operation pro;
'-'||TO_CHAR(PRO
----------------
- 12,35
由于所有空格,该字符串的转换失败。您可以通过稍微修改格式模型来避免这种情况:
with dlc_pr_operation (Sens_Mnt_Brut, Mnt_Brut, Mnt_Comm_Tot_Ope, Num_Est_Remise) as (
select 'D', 1234.56, 1, 2 from dual
)
select to_number('-' || TO_CHAR(PRO.Mnt_Brut,'FM99999999999,99')) from dlc_pr_operation pro;
TO_NUMBER('-'||TO_CHAR(PRO.MNT_BRUT,'FM99999999999,99'))
--------------------------------------------------------
-12,35
但前提是NLS设置,特别是NLS_数字_字符正确。如果我在执行alter session set nls\u numeric\u characters='之后运行相同的查询,“
那么这也会得到ORA-01722,因为您使用了固定的逗号。您可以显式更改会话,或者从使用固定的,
切换到通用的D
十进制分隔符:
alter session set nls_numeric_characters = '.,';
with dlc_pr_operation (Sens_Mnt_Brut, Mnt_Brut, Mnt_Comm_Tot_Ope, Num_Est_Remise) as (
select 'D', 1234.56, 1, 2 from dual
)
select to_number('-' || TO_CHAR(PRO.Mnt_Brut,'FM99999999999,99')) from dlc_pr_operation pro;
ORA-01722: invalid number
with dlc_pr_operation (Sens_Mnt_Brut, Mnt_Brut, Mnt_Comm_Tot_Ope, Num_Est_Remise) as (
select 'D', 1234.56, 1, 2 from dual
)
select to_number('-' || TO_CHAR(PRO.Mnt_Brut,'FM99999999999D99')) from dlc_pr_operation pro;
TO_NUMBER('-'||TO_CHAR(PRO.MNT_BRUT,'FM99999999999D99'))
--------------------------------------------------------
-1234.56
当然,在整个查询过程中,这仍然是隐式转换回数字
使用这个答案开头的修改过的查询(如果你还记得那么远的话)和一些更多的虚拟数据给出输出:
with dlc_pr_operation (Sens_Mnt_Brut, Mnt_Brut, Mnt_Comm_Tot_Ope, Num_Est_Remise) as (
select 'D', 1234.56, 1, 2 from dual
union all select 'X', 123.45, 2, 4 from dual
union all select 'Y', 456.78, 3, 4 from dual
)
select SUM(
CASE PRO.Sens_Mnt_Brut WHEN 'D' THEN -1 ELSE 1 END * PRO.Mnt_Brut
) OVER (PARTITION BY PRO.Num_Est_Remise)
- SUM(PRO.Mnt_Comm_Tot_Ope) OVER(PARTITION BY PRO.Num_Est_Remise) as result
From dlc_pr_operation pro;
RESULT
----------
-1235,56
575,23
575,23
由于没有转换,您的NLS设置现在无关紧要;除了最终结果由客户端使用会话的十进制分隔符自动格式化之外,因此在本例中它仍然显示逗号分隔符,数字字符设置为“”,.
。如果我将会话改为,“
,我会看到:
RESULT
----------
-1235.56
575.23
575.23
这是否是你真正想要的结果还不太清楚。包含其他列可能很有用,但您还需要检查是否真正需要分析函数,而不仅仅是聚合
你在评论中说: 这是一个数字(16.0),但我想在最后两个数字之前加一个逗号 这并没有真正的意义,除非你将财务金额存储为整数——本质上是便士/美分,而不是英镑/欧元/美元——但希望以更友好的方式显示它们;在这种情况下,您应该将它们除以100,而不是将它们作为字符串:
with dlc_pr_operation (Sens_Mnt_Brut, Mnt_Brut, Mnt_Comm_Tot_Ope, Num_Est_Remise) as (
select 'D', 123456, 100, 2 from dual
union all select 'X', 12345, 200, 4 from dual
union all select 'Y', 45678, 300, 4 from dual
)
select (SUM(
CASE PRO.Sens_Mnt_Brut WHEN 'D' THEN -1 ELSE 1 END * PRO.Mnt_Brut
) OVER (PARTITION BY PRO.Num_Est_Remise) / 100)
- (SUM(PRO.Mnt_Comm_Tot_Ope) OVER(PARTITION BY PRO.Num_Est_Remise) / 100) as result
From dlc_pr_operation pro;
RESULT
----------
-1235.56
575.23
575.23
。。。假设(再次)要求和的两个值都是这样存储的;如果愿意的话,您也可以减去这两个和,然后将总数除以100。您在数字和字符串之间进行了大量显式和隐式转换,不一致和假设让您感到困惑。但无论如何,它们都是不必要的——您根本不需要在字符串之间进行转换。您的查询可以重写为:
select SUM(
CASE PRO.Sens_Mnt_Brut WHEN 'D' THEN -1 ELSE 1 END * PRO.Mnt_Brut
) OVER (PARTITION BY PRO.Num_Est_Remise)
- SUM(PRO.Mnt_Comm_Tot_Ope) OVER(PARTITION BY PRO.Num_Est_Remise)
From dlc_pr_operation pro;
它只是根据Sens_Mnt_Brut
标志决定Mnt_Brut
是应按原样使用还是应取反,并将其乘以1或-1(视情况而定)
您的方法至少有两个问题。您使用显式格式模型将数字转换为字符串,然后隐式地将它们转换回数字以求和;这意味着(a)隐式转换依赖于NLS设置,以及(b)使用显式模型无法将正在生成的字符串转换回 让我们从一些将进入第一个分支的虚拟数据开始:
with dlc_pr_operation (Sens_Mnt_Brut, Mnt_Brut, Mnt_Comm_Tot_Ope, Num_Est_Remise) as (
select 'D', 1234.56, 1, 2 from dual
)
select to_number('-' || TO_CHAR(PRO.Mnt_Brut,'99999999999,99')) from dlc_pr_operation pro;
ORA-01722: invalid number
如果你看它形成的绳子,你会看到:
with dlc_pr_operation (Sens_Mnt_Brut, Mnt_Brut, Mnt_Comm_Tot_Ope, Num_Est_Remise) as (
select 'D', 1234.56, 1, 2 from dual
)
select '-' || TO_CHAR(PRO.Mnt_Brut,'99999999999,99') from dlc_pr_operation pro;
'-'||TO_CHAR(PRO
----------------
- 12,35
由于所有空格,该字符串的转换失败。您可以通过稍微修改格式模型来避免这种情况:
with dlc_pr_operation (Sens_Mnt_Brut, Mnt_Brut, Mnt_Comm_Tot_Ope, Num_Est_Remise) as (
select 'D', 1234.56, 1, 2 from dual
)
select to_number('-' || TO_CHAR(PRO.Mnt_Brut,'FM99999999999,99')) from dlc_pr_operation pro;
TO_NUMBER('-'||TO_CHAR(PRO.MNT_BRUT,'FM99999999999,99'))
--------------------------------------------------------
-12,35
但前提是NLS设置,特别是NLS_数字_字符正确。如果我在执行alter session set nls\u numeric\u characters='之后运行相同的查询,“
那么这也会得到ORA-01722,因为您使用了固定的逗号。您可以显式更改会话,或者从使用固定的,
切换到通用的D
十进制分隔符:
alter session set nls_numeric_characters = '.,';
with dlc_pr_operation (Sens_Mnt_Brut, Mnt_Brut, Mnt_Comm_Tot_Ope, Num_Est_Remise) as (
select 'D', 1234.56, 1, 2 from dual
)
select to_number('-' || TO_CHAR(PRO.Mnt_Brut,'FM99999999999,99')) from dlc_pr_operation pro;
ORA-01722: invalid number
with dlc_pr_operation (Sens_Mnt_Brut, Mnt_Brut, Mnt_Comm_Tot_Ope, Num_Est_Remise) as (
select 'D', 1234.56, 1, 2 from dual
)
select to_number('-' || TO_CHAR(PRO.Mnt_Brut,'FM99999999999D99')) from dlc_pr_operation pro;
TO_NUMBER('-'||TO_CHAR(PRO.MNT_BRUT,'FM99999999999D99'))
--------------------------------------------------------
-1234.56
当然,在整个查询过程中,这仍然是隐式转换回数字
使用这个答案开头的修改过的查询(如果你还记得那么远的话)和一些更多的虚拟数据给出输出:
with dlc_pr_operation (Sens_Mnt_Brut, Mnt_Brut, Mnt_Comm_Tot_Ope, Num_Est_Remise) as (
select 'D', 1234.56, 1, 2 from dual
union all select 'X', 123.45, 2, 4 from dual
union all select 'Y', 456.78, 3, 4 from dual
)
select SUM(
CASE PRO.Sens_Mnt_Brut WHEN 'D' THEN -1 ELSE 1 END * PRO.Mnt_Brut
) OVER (PARTITION BY PRO.Num_Est_Remise)
- SUM(PRO.Mnt_Comm_Tot_Ope) OVER(PARTITION BY PRO.Num_Est_Remise) as result
From dlc_pr_operation pro;
RESULT
----------
-1235,56
575,23
575,23
由于没有转换,您的NLS设置现在无关紧要;除了最终结果由客户端使用会话的十进制分隔符自动格式化之外,因此在本例中它仍然显示逗号分隔符,数字字符设置为“”,.
。如果我将会话改为,“
,我会看到:
RESULT
----------
-1235.56
575.23
575.23
这是否是你真正想要的结果还不太清楚。包含其他列可能很有用,但您还需要检查是否真正需要分析函数,而不仅仅是聚合
你在评论中说: 这是一个数字(16.0),但我想在最后两个数字之前加一个逗号 这并没有真正的意义,除非你将财务金额存储为整数——本质上是便士/美分,而不是英镑/欧元/美元——但希望以更友好的方式显示它们;在这种情况下,您应该将它们除以100,而不是将它们作为字符串:
with dlc_pr_operation (Sens_Mnt_Brut, Mnt_Brut, Mnt_Comm_Tot_Ope, Num_Est_Remise) as (
select 'D', 123456, 100, 2 from dual
union all select 'X', 12345, 200, 4 from dual
union all select 'Y', 45678, 300, 4 from dual
)
select (SUM(
CASE PRO.Sens_Mnt_Brut WHEN 'D' THEN -1 ELSE 1 END * PRO.Mnt_Brut
) OVER (PARTITION BY PRO.Num_Est_Remise) / 100)
- (SUM(PRO.Mnt_Comm_Tot_Ope) OVER(PARTITION BY PRO.Num_Est_Remise) / 100) as result
From dlc_pr_operation pro;
RESULT
----------
-1235.56
575.23
575.23
。。。假设(再次)要求和的两个值都是这样存储的;Y