动态order-by子句的运行时错误(静态等效子句有效)

问题描述 投票:1回答:3

问题是,是否有动态order-by子句触发的任何其他检查,而不是abap中的硬编码order-by子句。

我写了一个sql语句。本声明总结了特定年份的条目数。然后它根据条目的类型对计数进行分组。之后我尝试进行动态排序。由于某种原因,这会导致错误:“解析器产生错误:包含IN_YEAR的表达式不是GROUP-BY表达式。”

问题是,在对排序标准进行硬编码时,order-by子句正在工作。当我尝试动态地做它不会。

但是我必须动态地进行排序,因为稍后排序标准将来自oData(it_order)的前端。

DATA:    lv_cYear      TYPE NUMC4,
         lv_lYear      TYPE NUMC4,
         lv_2YearsAgo  TYPE NUMC4,

         lv_order_by   TYPE string.

GET TIME.
lv_cYear = sy-datum+0(4).
LV_LYEAR = LV_CYEAR - 1.
LV_2YEARSAGO = LV_CYEAR - 2.

*later lv_order_by should be filled dynamically
lv_order_by = 'RRC2019 DESCENDING, RRC2018 DESCENDING'.    

SELECT      
   type_name AS type,
   SUM( CASE WHEN in_year eq @lv_cYear THEN record_count END ) AS RRC2019,
   SUM( CASE WHEN in_year eq @lv_lyear THEN record_count END ) AS RRC2018,
   SUM( CASE WHEN in_year eq @LV_2YEARSAGO THEN record_count END ) AS RRC2017
FROM entryTable
   GROUP BY type_name
   HAVING SUM( CASE WHEN in_year eq @lv_cYear THEN record_count END ) IN @ls_in_2019_range-select_options
   AND SUM( CASE WHEN in_year eq @lv_lyear THEN record_count END ) IN @ls_in_2018_range-select_options
   AND SUM( CASE WHEN in_year eq @LV_2YEARSAGO THEN record_count END ) IN @ls_in_2017_range-select_options
   ORDER BY (lv_order_by)
   INTO CORRESPONDING FIELDS OF TABLE @et_entityset.

如果您尝试运行此错误“解析器产生错误:包含IN_YEAR的表达式不是GROUP-BY表达式”。

如果将“ORDER BY(lv_order_by)”替换为“RRC2019 DESCENDING ORDER BYER,RRC2018 DESCENDING”,它正在工作。

sql sql-order-by abap dynamic-sql
3个回答
2
投票

我使用@Jagger的程序并验证它在7.50中工作并从7.51开始中断。

这应该是一个bug。

更新:请申请注意2753729


1
投票

我只是允许自己准备一个可编辑的工作示例,它似乎与你所写的相反。我唯一改变的是INTO TABLE或(在你的情况下)INTO CORRESPONDING FIELDS OF TABLE @et_entityset的位置。

以下示例编译没有问题,也不会生成任何运行时异常。

REPORT YYY.

DATA:    lv_cYear      TYPE NUMC4,
         lv_lYear      TYPE NUMC4,
         lv_2YearsAgo  TYPE NUMC4,

         lv_order_by   TYPE string,
         ls_in_2019_range TYPE RANGE OF cosp-wtg001,
         ls_in_2018_range TYPE RANGE OF cosp-wtg001,
         ls_in_2017_range TYPE RANGE OF cosp-wtg001.

GET TIME.
lv_cYear = sy-datum+0(4).
LV_LYEAR = LV_CYEAR - 1.
LV_2YEARSAGO = LV_CYEAR - 2.

*later lv_order_by should be filled dynamically
lv_order_by = 'RRC2019 DESCENDING, RRC2018 DESCENDING'.

SELECT
   lednr AS type,
   SUM( CASE WHEN GJAHR eq @lv_cYear THEN wtg001 END ) AS RRC2019,
   SUM( CASE WHEN GJAHR eq @lv_lyear THEN wtg001 END ) AS RRC2018,
   SUM( CASE WHEN GJAHR eq @LV_2YEARSAGO THEN wtg001 END ) AS RRC2017
FROM cosp
   INTO TABLE @DATA(et_entityset)
   GROUP BY lednr
   HAVING SUM( CASE WHEN gjahr eq @lv_cYear THEN wtg001 END ) IN @ls_in_2019_range
   AND SUM( CASE WHEN gjahr eq @lv_lyear THEN wtg001 END ) IN @ls_in_2018_range
   AND SUM( CASE WHEN gjahr eq @LV_2YEARSAGO THEN wtg001 END ) IN @ls_in_2017_range
   ORDER BY (lv_order_by).

   BREAK-POINT.

1
投票

下面是一个编译所有最近基于ABAP的系统的示例(使用SAPBC_DATA_GENERATOR程序填充SFLIGHT表):

DATA: dummy_price TYPE sflight-price.

SELECT-OPTIONS sum_y1 FOR dummy_price DEFAULT 0 TO 99999.
SELECT-OPTIONS sum_y2 FOR dummy_price DEFAULT 0 TO 99999.

SELECT  substring( fldate, 1, 4 ) AS year,
        MIN( fldate )             AS low,
        MAX( fldate )             AS high
      FROM sflight
      GROUP BY substring( fldate, 1, 4 )
      ORDER BY year
      INTO TABLE @DATA(y).

ASSERT lines( y ) >= 2.

SELECT carrid,
   SUM( CASE WHEN fldate BETWEEN @( y[ 1 ]-low ) AND @( y[ 1 ]-high ) THEN price END ) AS sum_year1,
   SUM( CASE WHEN fldate BETWEEN @( y[ 2 ]-low ) AND @( y[ 2 ]-high ) THEN price END ) AS sum_year2
FROM sflight
   GROUP BY carrid
   HAVING SUM( CASE WHEN fldate BETWEEN @( y[ 1 ]-low ) AND @( y[ 1 ]-high ) THEN price END ) IN @sum_y1[]
      AND SUM( CASE WHEN fldate BETWEEN @( y[ 2 ]-low ) AND @( y[ 2 ]-high ) THEN price END ) IN @sum_y2[]
   ORDER BY SUM_YEAR1 DESCENDING, SUM_YEAR2 DESCENDING " <=== this works
 """"ORDER BY ('SUM_YEAR1 DESCENDING, SUM_YEAR2 DESCENDING') " <=== uncomment for short dump
   INTO TABLE @DATA(sflights).

LOOP AT sflights ASSIGNING FIELD-SYMBOL(<sflight>).
  WRITE : / <sflight>-carrid, <sflight>-sum_year1, <sflight>-sum_year2.
ENDLOOP.

在以下两个系统中,我重现了行为(它适用于静态ORDER BY子句,带有动态ORDER BY子句的短转储):

  • 开发人员版7.52 SP 1,带SYBASE ASE
  • S / 4HANA与ABAP 7.52 SP 0

毫无疑问,某处存在错误,但我无法找到解决问题的SAP说明。在SAP支持中打开票证会更好。

© www.soinside.com 2019 - 2024. All rights reserved.