Упрощаем работу с ADBC
С переходом на платформу HANA все актуальнее становится писать различного рода отчеты/программы с помощью «родных» NATIVE запросов к БД HANA, ведь используя встроенные механизмы и функции можно получить значительное преимущество перед OPEN SQL. В данной статье я не планирую переписывать все то, что можно найти в SСN или других ресурсах, но лишь хочу поделиться маленькими секретами, которые могут помочь каждому, кто ежедневно прикладывает руки к клавиатуре ради ABAPа (особенно начинающим).
С переходом на платформу HANA все актуальнее становится писать различного рода отчеты/программы с помощью «родных» NATIVE запросов к БД HANA, ведь используя встроенные механизмы и функции можно получить значительное преимущество перед OPEN SQL. В данной статье я не планирую переписывать все то, что можно найти в SСN или других ресурсах, но лишь хочу поделиться маленькими секретами, которые могут помочь каждому, кто ежедневно прикладывает руки к клавиатуре ради ABAPа (особенно начинающим). Информация в целом будет затрагивать элементарные возможности ADBC и особенности работы с диапазонами (RANGES).
Начну я с того, что ABAP Database Connectivity (сокращенно ADBC) стал для меня в последнее время весьма частым инструментом. Если кто-то еще не в курсе, то это новый объектный класс-инструмент для запросов к БД, появился он в ABAP release 6.10, но как сообщают источники, был задокументирован только в ABAP release 7.20. И можно однозначно сказать: он намного удобнее прежнего NATIVE SQL, но, как говорится, мнение читателя может не совпадать с мнением автора. Референс по ADBC вы можете найти на официальной странице http://help-legacy.sap.com/abapdocu_702/en/abenadbc.htm
Для демонстрации работы ADBC кратко приведу простой сниппет с комментариями для выбора, скажем, всех заказов за определённый год по сбытовой организации (возьмем код 1000) в разрезе месяца, клиента и материала, вычисляя их сумму с помощью агрегатной функции SUM:
Пример №1. Программа выбора заказов:
TYPES: BEGIN OF T_VBAP,
MONAT TYPE I,
VKORG TYPE VBAK-VKORG,
VTWEG TYPE VBAK-VTWEG,
KUNNR TYPE VBAK-KUNNR,
NAME1 TYPE KNA1-NAME1,
MATNR TYPE VBAP-MATNR,
ARKTX TYPE VBAP-ARKTX,
NETSUM TYPE VBAP-NETWR,
END OF T_VBAP.
DATA: LV_STATEMENT TYPE STRING.
DATA: LR_RESULT TYPE REF TO DATA.
DATA: LT_VBAP TYPE STANDARD TABLE OF T_VBAP.
DATA: LO_CONN TYPE REF TO CL_SQL_CONNECTION,
LO_STATEMENT TYPE REF TO CL_SQL_STATEMENT,
LO_RESULT_SET TYPE REF TO CL_SQL_RESULT_SET.
PARAMETERS: P_YEAR TYPE CHAR4,
P_VKORG TYPE VKORG.
START-OF-SELECTION.
Получаем ссылку на таблицу, куда будем «складывать» результат:
GET REFERENCE OF LT_VBAP INTO LR_RESULT.
Пишем запрос:
LV_STATEMENT =
| SELECT MONTH(VBAK.AUDAT) AS MONAT, VBAK.VKORG,VBAK.VTWEG,VBAK.KUNNR,KNA1.NAME1,VBAP.MATNR,VBAP.ARKTX, |
&& | SUM(VBAP.NETWR) FROM VBAP |
&& | INNER JOIN VBAK ON VBAK.MANDT = VBAP.MANDT AND VBAK.VBELN = VBAP.VBELN |
&& | INNER JOIN KNA1 ON KNA1.MANDT = VBAP.MANDT AND VBAK.KUNNR = KNA1.KUNNR WHERE |
&& | VBAP.MANDT = '{ sy-mandt }' AND |
&& | VBAK.VKORG = '{ P_VKORG }' AND |
&& | YEAR(VBAK.AUDAT) = '{ P_YEAR }' |
&& | GROUP BY MONTH(VBAK.AUDAT),VBAK.VKORG,VBAK.VTWEG,VBAK.KUNNR,KNA1.NAME1,VBAP.MATNR,VBAP.ARKTX |
&& | ORDER BY MONAT |.
TRY.
Получаем «коннект», создаем запрос, выполняем его и получаем весь результат в нашу таблицу:
LO_CONN = CL_SQL_CONNECTION=>GET_CONNECTION( ).
LO_STATEMENT = LO_CONN->CREATE_STATEMENT( ).
LO_RESULT_SET = LO_STATEMENT->EXECUTE_QUERY( LV_STATEMENT ).
LO_RESULT_SET->SET_PARAM_TABLE( LR_RESULT ).
LO_RESULT_SET->NEXT_PACKAGE( ).
LO_RESULT_SET->CLOSE( ).
CATCH CX_SQL_EXCEPTION.
WRITE:/ 'Что-то пошло не так'.
ENDTRY.
WRITE:/ 'Запрос выполнен'.
Кратко опишу использованные классы:
CL_SQL_CONNECTION – Класс для создания связи с БД.
CL_SQL_STATEMENT – Класс для выполнения операций SQL.
CL_SQL_PREPARED_STATEMENT – «родственник» класса CL_SQL_STATEMENT, позволяет создавать запросы с параметрами.
CL_SQL_RESULT_SET – Класс для обработки результатов запроса.
CX_SQL_EXCEPTION – Класс EXCEPTION.
Поясню также метод NEXT_PACKAGE. С помощью этого метода результат запроса выгружается в ссылочную таблицу, у метода два параметра:
UPTO - max. Anzahl zu lesender Datensätze (Знание немецкого языка не бывает бесполезным! )/ макс. Число данных для загрузки, т.е. число строк;
ROWS_RET - Anzahl gelesener Datensätze / число прочитанных строк.
Кстати, для того чтобы проверить запрос перед его вставкой в программу неплохо воспользоваться ST04 и поэксперементировать в редакторе SQL (Рис.1.):
Рис.1 ST04, Редактор SQL
Как видите, мы можем использовать массу преимуществ встроенных функций и выражений в HANA DB, используя такой подход, ведь даже используя элементарные функции для работы с датой и временем, а также весьма специфические для HANA DB, мы можем быстро формировать эффективные запросы для разработки отчетов любого типа. Но есть нюансы! А если нам нужны стандартные возможности работы, например, с RANGE (диапазонами)? Для этого можно использовать специальные классы для преобразования таблицы диапазонов в строку SQL, приведу два способа с помощью двух разных классов: с помощью класса CL_LIB_SELTAB и с помощью класса CL_SHDB_SELTAB.
Способ 1: Используем класс CL_LIB_SELTAB
Например, если мы зададим некую таблицу значений для выбора с именем S_VKORG, то можем «конвертировать» ее в готовую SQL строку для условия WHERE, используя данный код:
DATA: O_COND TYPE REF TO CL_LIB_SELTAB,
H_HANDLE TYPE REF TO CL_ABAP_TABLEDESCR,
L_COND TYPE STRING.
-----------------------------------------------
CALL METHOD CL_LIB_SELTAB=>NEW
EXPORTING
IT_SEL = S_VKORG[]
RECEIVING
RR_REF = O_COND.
CALL METHOD O_COND->SQL_WHERE_CONDITION
EXPORTING
IV_FIELD = 'VBAP.VKORG'
RECEIVING
RV_COND = WHERE_STR_VKORG.
В зависимости от содержания получим разные условия (BETWEEN,IN, OR и тд), затем полученную строку можно смело вставить в наш SQL код для выборки (пример №1):
LV_STATEMENT =
| SELECT MONTH(VBAK.AUDAT) AS MONAT, VBAK.VKORG,VBAK.VTWEG,VBAK.KUNNR,KNA1.NAME1,VBAP.MATNR,VBAP.ARKTX, |
&& | SUM(VBAP.NETWR) FROM VBAP |
&& | INNER JOIN VBAK ON VBAK.MANDT = VBAP.MANDT AND VBAK.VBELN = VBAP.VBELN |
&& | INNER JOIN KNA1 ON KNA1.MANDT = VBAP.MANDT AND VBAK.KUNNR = KNA1.KUNNR WHERE |
&& | VBAP.MANDT = '{ sy-mandt }' AND |
&& | ( { WHERE_STR_VKORG } ) AND
&& | YEAR(VBAK.AUDAT) = '{ P_YEAR }' |
&& | GROUP BY MONTH(VBAK.AUDAT),VBAK.VKORG,VBAK.VTWEG,VBAK.KUNNR,KNA1.NAME1,VBAP.MATNR,VBAP.ARKTX |
&& | ORDER BY MONAT |.
Замечу, что при пустой таблице, значение будет что-то вроде «(VBAK.VKORG LIKE ‘%’)». Но не торопимся радоваться! Меня ждал неприятный сюрприз: дело в том, что метод может неправильно конвертировать наши RANGES, «сливая» ,например, значения HIGH и LOW в одно значение поля LOW, краткая иллюстрация (Рис 2.):
Рис 2. Содержание перменной после обработки классом CL_LIB_SELTAB
Согласитесь, неприятно! А все потому, что структура для конвертации представлена в классе так:
types:
BEGIN OF ts_sel,
sign(1) TYPE c,
option(2) TYPE c,
low(30) TYPE c,
high(30) TYPE c,
Если хотите прочитать статью полностью и оставить свои комментарии присоединяйтесь к sapland
ЗарегистрироватьсяУ вас уже есть учетная запись?
Войти
Обсуждения 3
Комментарий от
Валерий Заузолков
| 24 мая 2017, 13:46
Только объясните, пожлста, след.момент: Если система на HANA, т.е. скорее всего базис будет 7.4, а м.б. и 7.5, соответственно, есть более удобный инструментарий - можно пользоваться новым синтаксисом Open SQL, CDS-view или AMDP, для вызова процедур или вьюшек созданных непосредственно в HANA (минуя ABAP-словарь), можно создавать прокси и вызывать через них.
Зачем ADBC в контексте HANA?
И, как мне кажется, к ADBC относятся те же рекомендации, что и к Native SQL - по возможности предпочитать Open SQL, в связи с тем, что NW оптимизирован под использование Open SQL.
Комментарий от
Леонид Мартынов
| 02 июня 2017, 11:41
Валерий Заузолков 24 мая 2017, 13:46
Просто как статья про ADBC - отлично!
Только объясните, пожлста, след.момент: Если система на HANA, т.е. скорее всего базис будет 7.4, а м.б. и 7.5, соответственно, есть более удобный инструментарий - можно пользоваться новым синтаксисом Open SQL, CDS-view или AMDP, для вызова процедур или вьюшек созданных непосредственно в HANA (минуя ABAP-словарь), можно создавать прокси и вызывать через них.
Зачем ADBC в контексте HANA?
И, как мне кажется, к ADBC относятся те же рекомендации, что и к Native SQL - по возможности предпочитать Open SQL, в связи с тем, что NW оптимизирован под использование Open SQL.
Я согласен для HANA актуальна HANA studio. Но я имел опыт с тем, что например доступ к ней разработчик по каким-либо причинам не имеет, а новый Open SQL не поддерживает всех возможностей, то при прочих равных удобно использовать ADBC со всеми плюсами сырого запроса к БД. То же касается и не HANA платформы, в любом случае цель была показать возможности ADBC! И большое вам спасибо за интерес к статье!
Комментарий от
Данил Жакаев
| 03 октября 2018, 01:04
Валерий Заузолков 24 мая 2017, 13:46
Просто как статья про ADBC - отлично!
Только объясните, пожлста, след.момент: Если система на HANA, т.е. скорее всего базис будет 7.4, а м.б. и 7.5, соответственно, есть более удобный инструментарий - можно пользоваться новым синтаксисом Open SQL, CDS-view или AMDP, для вызова процедур или вьюшек созданных непосредственно в HANA (минуя ABAP-словарь), можно создавать прокси и вызывать через них.
Зачем ADBC в контексте HANA?
И, как мне кажется, к ADBC относятся те же рекомендации, что и к Native SQL - по возможности предпочитать Open SQL, в связи с тем, что NW оптимизирован под использование Open SQL.
Так же через ADBC можно генерировать не только выборки, но и DDL.
Как пример, был опыт создания базового ABAP класса экстрактора из Calculation View из BW во внешние системы - в классе-наследнике просто указываешь в атрибут имя CV и переопределяешь метод для заполнения placeholders - и оно работает динамически.