Ранее я писал об возможности делать SQL запрос к Hana модели из ABAP, предварительно не создавая результирующую структуру, а так же описал принцип работы этого подхода.
Если добавить в эту схему GUI ввода и вывода, то получится своеобразная консоль с усеченными возможностями.
Реализация
В качестве поля для ввода текста я использовал стандартный класс cl_gui_textedit, на экране у меня будет поле ввода по ограничению количества строк вывода, буду отслеживать время затраченное на выполнения запроса.
Экран ввода текста
У меня он называется ‘0200’.
Контейнер называется TEXTEDITOR , поле ввода ROWS, кнопка вызывает user-command EXECUTE.
В статус добавим кнопку завершения программы,
PBO для этого экрана
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
data: editor_container type ref to cl_gui_custom_container, text_editor type ref to cl_gui_textedit. ...... if text_editor is initial. editor_container = new #( container_name = 'TEXTEDITOR' ). text_editor = new #( parent = editor_container wordwrap_mode = cl_gui_textedit=>wordwrap_off wordwrap_position = 254 wordwrap_to_linebreak_mode = cl_gui_textedit=>false ). text_editor->set_toolbar_mode( toolbar_mode = cl_gui_textedit=>false ). text_editor->set_statusbar_mode( statusbar_mode = cl_gui_textedit=>false ). endif. |
PAI
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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
*&---------------------------------------------------------------------* *& Module USER_COMMAND_0200 INPUT *&---------------------------------------------------------------------* MODULE USER_COMMAND_0200 INPUT. case sy-ucomm. when 'OUT'. leave program. when 'BACK'. leave to screen 0. when 'EXECUTE'. clear sql. text_editor->get_textstream( importing text = sql ). cl_gui_cfw=>flush( ). perform execute_query. endcase. ENDMODULE. *&---------------------------------------------------------------------* *& Form EXECUTE_QUERY *&---------------------------------------------------------------------* FORM EXECUTE_QUERY. data: input_parameters type string, data_tab type ref to data, schema type string. free data_tab. if <tab> is assigned. free: <tab>. endif. *удаляем лишние символы call function 'SCP_REPLACE_STRANGE_CHARS' exporting intext = sql replacement = 32 importing outtext = sql. data comm type string. get run time field data(ts_start). data_tab = zcl_sql_executor=>result_hana_model( exporting i_query = sql importing e_catalog = fieldcatalog e_patch = catalog_name e_model_name = cube_name e_comm = comm ). get run time field data(ts_end). timepassed_seconds = ts_end - ts_start. assign data_tab->* to <tab>. if comm is initial. call screen 100. else. message comm type 'I'. endif. ENDFORM. |
Итак, при вводе SQL команды и нажатии на кнопку EXECUTE, текст считывается в переменную sql, далее при помощи ФМ SCP_REPLACE_STRANGE_CHARS из этой строки удаляются все лишние символы (например символы переноса строки). Параметр replacement это код ASCII на который будут заменяться найденные литералы. 32 код пробела.
Далее вызывается метод zcl_sql_executor=>result_hana_model(), который я описал в прошлой статье. Замеряем время исполнения оператором get run time. Присваиваем ссылку <tab>. На этом этапе у нас есть все, что бы вывести результаты в ALV.
Для большей аутентичности, можно сделать вывод в docking container, допустим снизу, но в этом примере я сделал вывод на отдельный экран.
Экран вывода
У меня экран вывода называется ‘0100’.
В статусе добавим кнопки BACK и OUT.
Title bar зададим следующим образом.
1 |
set titlebar 'BAR100' with catalog_name cube_name. |
PAI
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 |
*&---------------------------------------------------------------------* *& Module GRID_INIT OUTPUT *&---------------------------------------------------------------------* module GRID_INIT output. if container is not initial. grid->free( ). container->free( ). endif. free: container, grid. container = new #( side = cl_gui_docking_container=>dock_at_top extension = cl_gui_docking_container=>ws_maximizebox ). grid = new #( container ). data: layout type lvc_s_layo. layout-cwidth_opt = abap_true. layout-grid_title = |Время исполнения { timepassed_seconds } ms|. grid->set_table_for_first_display( exporting is_layout = layout changing it_outtab = <tab> it_fieldcatalog = fieldcatalog ). endmodule. |
Получился такой вариант. При нажатии кнопки назад и исполнении кнопки EXECUTE элементы экрана фактически пересоздаются. Пойти на это пришлось из-за метода cl_gui_cfw=>flush( ). Наверно решить эту проблему можно и более элегантным способом.
PAI
1 2 3 4 5 6 7 8 9 10 11 |
*&---------------------------------------------------------------------* *& Module USER_COMMAND_0100 INPUT *&---------------------------------------------------------------------* module USER_COMMAND_0100 input. case sy-ucomm. when 'OUT'. leave program. when 'BACK'. set screen 0. endcase. endmodule. |
Результаты работы
Запустим приложение введем SQL запрос из прошлых статей, в качестве входящего параметра установим EUR.
Нажмем EXECUTE
Как видно, заголовок принял значение модели, в заголовке таблицы время исполнения.
Теперь нажмем кнопку назад (в статус сверху), поменяем входящий параметр на USD и ограничим количество записей до 10. В select поставим звездочку (*)
Видим следующий результат.
Поля все вывелись, но в другом порядке, к сожалению нормального способа отсортировать их при вызове со звездочкой нет.
Допустим ошибку в запросе (убрал запятую после «SEATSOCC_F»).
Ключевая разница с обычной консолью
Пользователь, под которым вы вызываете консоль и пользователь, под которым вызывается SQL команда из ABAP, это разные пользователи, с разным количеством привилегий. Зачастую (не всегда) бывает прав на запуск команд из консоли меньше чем из ABAP.
Исходный код
Исходный код этого приложения можно найти по ссылке.
Для запуска необходимо скопировать. содержимое ZCL_SQL_EXECUTOR.abap и ZHANA_VIEWER.abap. Добавить экраны. На экране ввода текста расположить элементы как показано в этой статье выше.