Все больше в настоящее время SAP систем переходят на новую платформу (СУБД) – HANA (High-Performance Analytic Appliance), в основе которой лежит технология вычислений in-memory с использованием принципа поколоночного хранения данных. Вместе с новой платформой, появляются так же и новые возможности для обработки больших объемов данных и более высокопроизводительных вычислений.
Для ускорения ABAP решений на базе HANA, используется перенос вычислений с уровня сервера приложений (AS ABAP) на сервер СУБД (Code-to-Data). Данную задачу можно решить несколькими способами, одним из которых является использование Native SQL и AMDP как средства его вызова.
В контексте ABAP разработки, под Native SQL понимается язык SQL запросов поддерживаемый текущей или дополнительной СУБД сервера приложений.
В данной статье будут рассмотрены основные моменты использования AMDP.
SAP рекомендует использовать Native SQL в ABAP только тогда, когда задачу оптимизации не решить стандартными средствами OpenSQL, в частности AMDP следует использовать только если будут задействованы какие-то специфичные для HANA вещи или объем данных слишком велик чтобы переносить его между СУБД и сервером приложений.
Вызывать Native SQL в ABAP напрямую можно несколькими методами, среди которых:
Косвенно через:
- External Procedures (proxies). Рекомендуется использовать только если невозможно тоже самое сделать через AMDP (например, когда HANA подключена как дополнительная СУБД),
- External views (если учесть что view будет к calculation view на базе SQL Script), так же не рекомендуется к использованию если возможно тоже самое реализовать через ABAP CDS или AMDP.
Наиболее удобным и современным способом вызова Native SQL является использование AMDP, преимущества заключаются в следующем:
- Проверка синтаксиса и подсветка команд,
- Стандартное для ABAP объектов управление жизненным циклом (В отличие от внешних процедур и ракурсов, где необходимо использовать HANA артефакты для переноса объекта между системами),
- Автодополнение и навигация к используемым объектам,
- Простой вызов из ABAP.
Технически AMDP это обёртка над хранимыми процедурами в СУБД. Обёртка заворачивает Native SQL код в методы ABAP класса (AMDP методы), которые Вы можете использовать в своих программах как обычные методы обычных классов. Во время первого доступа к такому методу, на сервере БД будет создана хранимая процедура, которая создаётся в основной схеме для сервера приложений с именем SAPSid, где Sid – идентификатор системы. Доступ из хранимой процедуры можно получить к объектам БД текущей схемы (SAPSid) и объектам других схем, явно указав их имена.
В настоящее время AMDP поддерживается только для HANA, однако в будущем планируется поддержка других СУБД. Проверить поддержку AMDP можно через класс CL_ABAP_DBFEATURES и его метод CALL_AMDP_METHOD (ABAP 7.5).
Под Native SQL в HANA подразумеваются языки SQL Script и L, однако L доступен только для разработчиков SAP.
AMDP классы
Как и большинство новых объектов разработки, AMDP классы доступны для редактирования только из ADT (ABAP Development Tools for Eclipse). Создаётся AMDP класс таким же образом, как и обычные глобальные классы, единственным отличаем, является реализация классом специального интерфейса — IF_AMDP_MARKER_HDB. Данный интерфейс является своего рода меткой для системы, чтобы она понимала, что в методах этого класса может быть встроен вызов AMDP. Кроме AMDP методов такой класс может содержать и обычные методы.
AMDP методы
Метод AMDP может быть как статическим, так и методом инстанции с любой видимостью. По своему описанию в заголовке класса он ничем не отличается от обычных методов. Понять, что это AMDP метод можно только заглянув в исходный код.
На AMDP метод накладываются определенные ограничения.
Ограничения в интерфейсе:
- Нельзя использовать обобщенные типы (TYPE DATA, TYPE CSEQUENCE и др.), доступны только элементарные типы данных и табличные, компоненты которых являются элементарными.
- Нельзя использовать для описания типа устаревшие словарные типы — DF16_SCL и DF34_SCL.
- Параметры всегда должны переноситься по значению, перенос по ссылке недоступен.
- RETURNING параметры запрещены.
- Только входные параметры могут быть помечены как необязательные и для всех необязательных параметров необходимо, чтобы было задано начальное значение.
- Параметры с типами f, decfloat16, decfloat34, string, и xstring не могут быть со значением по умолчанию, а значит, они не могут быть необязательными.
- Имена параметров:
- Не могут начинаться с префикса «%_».
- Нельзя использовать параметры с именами: endmethod и client.
- Если используется параметр с именем connection, он обязательно должен иметь тип — DBCON_NAME, используется он когда AMDP вызывается через сервисное подключение, в таком случае его адрес необходимо будет передать через параметр.
- При описании исключений можно использовать только заранее определенные классы исключений. Классические исключения недоступны.
- CHANGING параметры не могут иметь тип string или xstring.
- Длина параметров с типом C или N не может превышать 5000 символов.
Ограничения в рамках реализации:
- Нельзя использовать DDL синтаксис.
- Локальные временные объекты БД не могут быть доступны из метода.
- Запрещено использование rollback или commit. Транзакции должны быть обработаны в рамках ABAP программ.
- Доступ на запись к словарным таблицам, для которых активна буферизация — запрещен.
- AMDP методы не могут содержать внутри себя неявных расширений.
- AMDP метод не может быть пустым.
- Конструктор нельзя реализовать как AMDP метод.
В ABAP 7.4. можно реализовать только метод AMDP процедуры, в 7.5 добавилась так же возможность создания метода AMDP функции. AMDP функции можно использовать для получения данных в других AMDP процедурах и функциях, в ABAP CDS и даже в OpenSQL. Для функций параметр RETURNING является обязательным. В статье реализация функций не рассматривается, подробнее о функциях смотрите в документации.
Для AMDP методов, как и для обычных методов доступна поддержка наследования, пример использования можно посмотреть в программе — demo_amdp_polymorphism. Таким образом, можно сделать разные реализации и в зависимости от поддержки AMDP, вызывать либо их, либо обычные методы с OpenSQL.
Так как AMDP это Native SQL, поддержка клиента (манданта) должна быть реализована вручную, как правило клиент предаётся внутрь AMDP как параметр. Другим способом является возможность использования специальной функции – SESSION_CONTEXT, использовать которую следует, только если ваша AMDP процедура вызывается из ABAP.
Как уже говорилось выше, понять, что это AMDP метод можно только по исходному коду. Меткой для системы в таком случае служит дополнение BY DATABASE PROCEDURE у выражения – METHOD.
Синтаксис этого дополнения следующий:
1 2 3 4 5 6 7 |
METHOD meth BY DATABASE PROCEDURE FOR db LANGUAGE db_lang [OPTIONS db_options] [USING db_entities]. ... ENDMETHOD. |
Дополнение FOR определяет, для какой СУБД создана текущая AMDP процедура. В настоящее время доступно только определение для HANA:
db | СУБД | Интерфейс |
HDB | SAP HANA | IF_AMDP_MARKER_HDB |
В будущем, возможно, появится поддержка других СУБД, тогда можно будет использовать несколько маркеров (интерфейсов), чтобы реализовывать методы для разных СУБД.
Дополнение LANGUAGE определяет то, на каком языке будет реализация AMDP процедуры. Доступны следующие варианты:
db | db_lang | Язык | Комментарий |
HDB | SQLSCRIPT | SQLScript | Доступно для всех |
HDB | LLANG | L | Доступно только внутри SAP |
Дополнение OPTIONS описывает специфичные для СУБД параметры обработки AMDP. Доступные следующие варианты:
db | option | Значение |
HDB | READ-ONLY | В рамках AMDP нельзя будет изменять значения таблиц. |
HDB | SUPPRESS SYNTAX ERRORS | Для внутреннего использования SAP. |
Основным по значимости дополнением является дополнение USING. В рамках него указывается, какие объекты СУБД будут обработаны в текущей реализации AMDP. Указание объектов необходимо прежде всего для того, чтобы система могла выполнить соответствующие проверки синтаксиса.
Необходимо указывать следующие объекты:
- Все таблицы и ракурсы из ABAP словаря.
- Все процедуры (или функции ABAP 7.5) AMDP, даже если они из одного класса.
Все остальные объекты (не управляемые из ABAP) не могут присутствовать в дополнении USING. Указанные в USING объекты должны присутствовать в текущей схеме БД и могут использоваться без её указания. Объекты из других схем должны использоваться с указанием полного имени, в том числе имени схемы, исключением являются объекты из текущей схемы с префиксом — /1BCAMDP/.
Объекты из USING должны обязательно быть использованы в реализации AMDP процедуры.
Пример вызова одной AMDP процедуры из другой:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
METHOD increase_price BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT USING cl_demo_amdp_call_amdp=>increase_price_amdp. call "CL_DEMO_AMDP_CALL_AMDP=>INCREASE_PRICE_AMDP"( CLNT => :CLNT, INCPRICE => :INCPRICE ); ENDMETHOD. METHOD increase_price_amdp BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT USING sflight. update sflight set price = price + incprice where mandt = clnt; ENDMETHOD. |
Как видно из примера, в процедуре через дополнение USING была описана используемая в реализации другая AMDP процедура.
Из-за ограничений HANA, рекурсивные и циклические вызовы в AMDP процедур запрещены.
AMDP BADI
AMDP классы могут быть использованы в расширениях через специальные AMDP BAdi, с определенными ограничениями в сравнении с обычными BAdi.
Ограничения в определении и реализации:
- Нельзя использовать фильтры
- Fallback класс должен быть всегда определен (Реализация BAdi по умолчанию).
- Каждый метод BAdi должен быть реализован через AMDP процедуру.
Вызываются такие AMDP BAdi так же как и стандартные Kernel BAdi через GET BADI, CALL BADI.
В следующем видео подробно с примерами разобрано использование AMDP BAdi:
Отладка AMDP
Для отладки AMDP в ABAP 7.4. необходимо сделать предварительные настройки:
- Настроить внешнюю отладку и поставить точку останова в HANA Studio,
- Выдать соответствующие полномочия пользователю в HANA, под которым будет выполнена отладка.
После чего можно использовать Procedure Debugger в HANA Studio, вызвав процедуру из ABAP.
В ABAP 7.5. отладку процедур можно выполнять прямо в ADT без HANA Studio, используя новый для этой версии инструмент ADT — AMDP Debugger.
На тему отладки AMDP процедур в ABAP 7.4 на SCN есть хорошая статья.
Так же доступно видео с полным разбором:
SQL Script
Синтаксис языка SQL Script описан в соответствующей документации (обратите внимание на версию HANA в документе). В AMDP могут быть использованы CE_* функции которые работают с любыми типами View (CE_COLUMN_TABLE не будет работать, так как эта функция работает только с column store). Однако по заявлениям некоторых представителей SAP, данные функции отживают свое и возможно скоро будут считаться устаревшими.
Пример использования CE_UNION_ALL:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
CLASS zcl_amdp_test_case1 DEFINITION PUBLIC FINAL CREATE PUBLIC . PUBLIC SECTION. INTERFACES: if_amdp_marker_hdb. CLASS-METHODS: amdp_get_aa EXPORTING VALUE(et_aa) TYPE SPFLI_TAB RAISING cx_amdp_error, amdp_get_ua EXPORTING VALUE(et_ua) TYPE SPFLI_TAB RAISING cx_amdp_error, amdp_get_all EXPORTING VALUE(et_all) TYPE spfli_tab RAISING cx_amdp_error. PROTECTED SECTION. PRIVATE SECTION. ENDCLASS. CLASS zcl_amdp_test_case1 IMPLEMENTATION. METHOD amdp_get_aa BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT USING spfli. et_aa = SELECT * FROM spfli WHERE carrid = 'AA'; ENDMETHOD. METHOD amdp_get_ua BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT USING spfli. et_ua = SELECT * FROM spfli WHERE carrid = 'UA'; ENDMETHOD. METHOD amdp_get_all BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT USING zcl_amdp_test_case1=>amdp_get_aa zcl_amdp_test_case1=>amdp_get_ua. call "ZCL_AMDP_TEST_CASE1=>AMDP_GET_AA"( ET_AA => :lt_aa ); call "ZCL_AMDP_TEST_CASE1=>AMDP_GET_UA"( ET_UA => :lt_ua ); et_all = CE_UNION_ALL(:lt_aa, :lt_ua ); ENDMETHOD. ENDCLASS. |
Одной из типичных проблем, с которыми сталкивается разработчик при использовании AMDP – передача RANGE с экрана выбора. Решается задача путём формирования WHERE условия с помощью класса — CL_SHDB_SELTAB и его применения к выбранным данным через SQL Script функцию APPLY_FILTER, пример можно посмотреть в статье на SCN.
Если данного класса нет в Вашей системе, он может быть установлен нотой.
При обработке данных получаемых из ABAP система сопоставляет типы ABAP и HANA по следующим правилам:
ABAP Тип | HANA Тип | Комментарий |
b | SMALLINT | — |
s | SMALLINT | — |
i | INTEGER | — |
p, длинна leng с dec знаками после запятой | DECIMAL, длинна 2 leng-1 c dec знаками после запятой | — |
decfloat16 | VARBINARY, длинна 8 | Вычисления как с числовыми типами система произвести не сможет |
decfloat34 | VARBINARY, длинна 16 | Вычисления как с числовыми типами система произвести не сможет |
f | DOUBLE | — |
c, длинна len | NVARCHAR, длинна len | — |
string | NCLOB | Не разрешено для CHANGING параметров AMDP |
n, длинна len | NVARCHAR, длинна len | Для использования в арифметических выражениях следует использование преобразование типа к числовому типу HANA |
d | NVARCHAR, длинна 8 | Для использования в расчётах с датой необходимо преобразование к типу даты в HANA |
t | NVARCHAR, длинна 6 | Для использования в расчётах с временем необходимо преобразование к типу времени в HANA |
x, длинна len | VARBINARY, длинна len | — |
xstring | BLOB | Не разрешено для CHANGING параметров AMDP |
Типы ABAP словаря сопоставляются так же как и сопоставимые с ними ABAP типы, за исключением:
DF16_DEC, длинна leng с dec знаками после запятой | DECIMAL, длинна 2len-1 с dec знаками после запятой | Тип в HANA имеет меньший диапазон значений, чем в ABAP |
DF34_DEC, длинна leng с dec знаками после запятой | DECIMAL, длинна 2len-1 с dec знаками после запятой | Тип в HANA имеет меньший диапазон значений, чем в ABAP |
DF16_SCL | — | Устарело, не поддерживается |
DF34_SCL | — | Устарело, не поддерживается |
SSTRING, длинна len | NVARCHAR, длинна len | — |
как всегда, большое спасибо за статью (жалко только, что не на полгода раньше)
Всегда пожалуйста!
В последнем куске кода использование CE_UNION_ALL не оправдано, потому что по рекомендациям от SAPа нельзя смешивать CE функции с чистым sql или с sqlscriptом и даже может быть в данном конкретном случае это не вызовет каких то «торможений»( более плохая оптимизация ) или искажений в данных, но это сделано не по best practice’ам . Это во-первых. А во-вторых на текущий момент SAP вообще не рекомендует использовать CE функции поскольку они уже устарели, и развиваться не будут. Сейчас только SQLScript.
Все верно, CE функции уже устарели. Вообще относительно SQL скрипта крайне желательно всегда смотреть на актуальную версию гайда. Примеры же сделаны были исключительно ради демонстрации возможностей AMDP. Best practice есть в тех же гайдах.