ABAP中CASE语句内WRBTR字段计算触发小数位数超限错误
解决ABAP SQL中CASE语句处理WRBTR时的精度错误问题
原始实现逻辑
最初先通过SELECT获取数据,再循环调整特定条件下的金额符号:
SELECT FROM bseg LEFT JOIN aufk ON ( ltrim( aufk~aufnr, '0' ) = bseg~zuonr ) JOIN bkpf ON bkpf~belnr = bseg~belnr AND bkpf~gjahr = bseg~gjahr AND bkpf~bukrs = bseg~bukrs FIELDS bseg~bukrs, bseg~bschl, bseg~wrbtr, bseg~h_hwaer INTO TABLE @DATA(output). LOOP AT output ASSIGNING FIELD-SYMBOL(<output>) WHERE bschl = '50'. <output>-wrbtr = <output>-wrbtr * ( -1 ). ENDLOOP.
使用CASE语句优化时的错误
为去掉循环,改用ABAP 7.4+支持的CASE语句在SQL中直接处理,编写语句如下:
SELECT FROM bseg LEFT JOIN aufk ON ( ltrim( aufk~aufnr, '0' ) = bseg~zuonr ) JOIN bkpf ON bkpf~belnr = bseg~belnr AND bkpf~gjahr = bseg~gjahr AND bkpf~bukrs = bseg~bukrs FIELDS bseg~bukrs, CASE WHEN bseg~bschl = '50' THEN bseg~wrbtr * ( -1 ) ELSE bseg~wrbtr END AS bseg~wrbtr, bseg~h_hwaer INTO TABLE @DATA(output).
执行时触发错误:
以WRBTR开头的表达式最多可包含34位(含2位小数),但实际允许最多31位(含14位小数)。
尝试错误的CAST写法:
- 缺少目标类型的CAST:
WHEN bseg~bschl = '50' THEN CAST( bseg~wrbtr * ( -1 ) )
得到错误:")" is invalid here (due to grammar).
- 使用无效类型名的CAST:
WHEN bseg~bschl = '50' THEN CAST( bseg~wrbtr AS test ) * ( -1 )
得到错误:"TEST" is invalid here (due to grammar).
正确解决方案
问题源于乘法运算导致的精度溢出,需要将运算结果CAST回与WRBTR完全匹配的数据类型(通常是CURR对应的数据库DECIMAL类型,精度和小数位与表字段一致)。
正确写法如下:
SELECT FROM bseg LEFT JOIN aufk ON ( ltrim( aufk~aufnr, '0' ) = bseg~zuonr ) JOIN bkpf ON bkpf~belnr = bseg~belnr AND bkpf~gjahr = bseg~gjahr AND bkpf~bukrs = bseg~bukrs FIELDS bseg~bukrs, CASE WHEN bseg~bschl = '50' THEN CAST( bseg~wrbtr * (-1) AS bseg~wrbtr ) ELSE bseg~wrbtr END AS wrbtr, bseg~h_hwaer INTO TABLE @DATA(output).
关键说明:
- 直接引用
bseg~wrbtr作为CAST的目标类型,确保精度和小数位与原字段完全一致,避免溢出错误。 - 也可以显式写出对应的数据类型(比如
CAST( ... AS DECIMAL(15,2) )),但引用字段类型的方式更灵活,适配不同系统中WRBTR的定义差异。
内容的提问来源于stack exchange,提问作者schmelto
相关产品推荐
相关产品推荐

