Ошибка времени выполнения для предложения динамического упорядочения (предложение статического эквивалента работает) - PullRequest
0 голосов
/ 07 февраля 2019

Вопрос в том, есть ли какие-либо другие проверки, запускаемые для динамических предложений order-by, а не для жестко закодированных предложений order-by в abap.

Я написал в abap выражение 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)» на «ORDER BYRRC2019 DESCENDING, RRC2018 DESCENDING "это работает.

Ответы [ 3 ]

0 голосов
/ 07 февраля 2019

Вот пример, который компилируется во всех последних системах на основе 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):

  • Developer Edition 7.52 SP 1 с SYBASE ASE
  • S / 4HANA с ABAP 7.52 SP 0

Нет сомнений, что где-то есть ошибка, но я не смог найти SAP-ноту, чтобы исправить проблему.Так было бы лучше открыть заявку в службу поддержки SAP.

0 голосов
/ 08 февраля 2019

Я использовал программу @ Jagger и проверил, что она работает в 7.50 и ломается, начиная с 7.51.

Это должно быть ошибкой.

Обновление: пожалуйста, обратите внимание 2753729

0 голосов
/ 07 февраля 2019

Я просто позволил себе подготовить компилируемый рабочий пример, и, похоже, он работает вопреки тому, что вы написали.Единственное, что я изменил, - это расположение 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.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...