我有如下选择:
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).
当select完成时,I遍历output
表,在bschl = '50'
时进行计算。
LOOP AT output ASSIGNING FIELD-SYMBOL(<output>) WHERE bschl = '50'.
<output>-wrbtr = <output>-wrbtr * ( -1 ).
ENDLOOP.
自从ABAP 7.4我可以在SQL选择中使用CASE
语句。这就是我想要用来摆脱循环的方法。
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位。
我也试过castbseg~wrbtr
:
WHEN bseg~bschl = '50' THEN CAST( bseg~wrbtr * ( -1 ) )
→")" is invalid here (due to grammar).
或
WHEN bseg~bschl = '50' THEN CAST( bseg~wrbtr AS test ) * ( -1 )
→"TEST" is invalid here (due to grammar).
有人知道怎么处理这个吗?
我的答案是通过* -1
设置一个标志。它不适用于与其他数的乘法。
在ABAP 7.52和S/4HANA 1709中,BSEG-WRBTR
仍然是一个包含2个小数的封装的7字节数,除了END AS bseg~wrbtr
导致错误"~" is invalid here (due to grammar)
并且必须用END AS wrbtr
替换,语法在我的系统中是有效的.
在我的系统中,输出表的内联声明选择了一个包含2位小数的封装的13字节数。它是使输出表中的位数乘以2(从7字节到13字节)的乘法。作为比较,加法只声明一个打包的8字节数。
我猜你有一个最近的S/4HANA版本,BSEG-WRBTR
有更多的数字(功能称为"数量字段长度扩展"),这就是为什么乘法使内联声明产生一个无效的类型,有太多的数字。
解决方法:如果你签名而不相乘,它将保持相同的位数(在我的情况下是打包的7字节数),这种语法也应该适用于你的情况:
CASE bseg~bschl
WHEN '50' THEN - bseg~wrbtr "<=== negative sign, is not the same logic as * -1
ELSE bseg~wrbtr
END AS wrbtr
EDIT Dec 30 -我没有在ABAP文档中找到一个明确的参考,如何为算术SQL表达式计算内联类型,它是通过搜索"up"从我所经历的行为中,我可以找到一条合乎逻辑的方式";
- SELECT, INTO target - @DATA(dobj):
SQL表达式的结果类型对应的ABAP类型
- sql_exp - sql_arith(涉及+,-,*和/):
除了任何整数操作数(见上文)外,十进制表达式至少有一个操作数类型为DEC、CURR、QUAN或p。十进制表达式中不允许使用/运算符。结果类型为DEC,长度为31,小数点后最多14位。使用关联的分配规则,它可以赋值给所有值范围足够大的数值ABAP类型,除了十进制浮点数。
- SELECT,赋值规则:
如果目标字段是数字数据类型,则结果字段的值转换为该数据类型,并且目标字段的值范围必须足够大。这里,在CURR、DEC或QUAN类型的结果字段中任何多余的小数点(BCD格式的数字)都被截断.
正确的CASE语法:
CASE bseg~bschl
WHEN '50' THEN bseg~wrbtr * ( -1 )
ELSE bseg~wrbtr
END AS bseg~wrbtr
将bseg~bschl移到case和WHEN后面,只提到相等的值
在您的CASE中,CAST( bseg~wrbtr AS D34N ) * CAST( -1 AS D34N )
的计算结果被放入类型为计算类型的数据对象中。
根据文档,WRBTR (ABAP类型p)的计算类型也是p,但需要注意的是:
对内联声明赋值时的计算类型p可以产生长度为8且没有小数点的数据类型p,这会产生意想不到的结果并引发异常
<解决方案/strong>:从select查询中删除内联声明INTO TABLE @DATA(output)
,并提前以适当的精度声明itab。
这是我对这个问题的工作解决方案。
CASE bseg~bschl
WHEN '50' THEN CAST( bseg~wrbtr AS D34N ) * CAST( -1 AS D34N )
ELSE CAST( bseg~wrbtr AS D34N )
END AS wrbtr, bseg~h_hwaer,