Консоль запросов для SAP ERP. Выполнение SQL-запросов
В этой статье я хочу рассказать о том, с какими проблемами мы столкнулись в процессе внедрения SAP ERP при разработке ABAP-программ и какой инструмент нам помог оптимизировать этот процесс.
Системный ландшафт и процесс разработки ABAP-программ
При внедрении информационно-управляющей системы на базе SAP ERP, как правило, разворачивается комплекс систем:
- Система разработки.
- Система тестирования.
- Система продуктивной эксплуатации.
Система разработки обычно содержит минимум данных и полноценно протестировать написанную программу в этой системе не получается. Код из системы разработки переносится в другие с помощью, так называемых, транспортных запросов.
Стандартная ситуация: программист пишет код в системе разработки, переносит его в тестовую систему и в процессе тестирования обнаруживает, что написанный код работает некорректно, после чего он возвращается в систему разработки для исправления ошибок, а затем повторно переносится в тестовую систему (Рис. 1). Этот процесс зацикливается, и каждая такая итерация отнимает около десяти «непродуктивных» минут, которые разработчик тратит на рутинные действия по переносу запроса. И таких итераций может потребоваться много.
Бывают также ситуации, когда в тестовой системе программа отрабатывает нормально, разработчик переносит ее в продуктивную систему и видит, что имеются серьезные проблемы с производительностью этой программы. В тестовой системе это не проявлялось, потому что объем данных в ней был не такой большой, как в продуктивной системе, или нагрузка на БД была меньше. И опять разработчик возвращается в систему разработки, чтобы оптимизировать программный код. Теперь каждая итерация у него будет занимать еще больше времени, так как, в большинстве случаев, перенос изменений в продуктивную систему сопровождается цепочкой согласований изменений с разными ответственными лицами.
Рис. 1. Системный ландшафт
Оптимизация процесса разработки
Поняв, что теряем много времени на подобные вещи, мы пришли к выводу, что нужно этот процесс оптимизировать: надо уменьшить число итераций по исправлению кода и таким образом сократить общее время разработки (Рис. 2).
Рис. 2. Оптимизация Системного ландшафта
В первую очередь мы обратили внимание на SQL-запросы. Они часто бывают самым слабым местом в коде: либо данные выбираются некорректно, либо выбираются очень медленно.
Те, кто знаком с разработкой на 1С, знают, что там есть инструмент, который называется «Консоль запросов», позволяющий выполнять произвольные запросы напрямую в продуктивной системе без дополнительных разработок. Мы решили, что нам нужен такой же инструмент для SAP, то есть нам требуется инструмент, который бы позволял оперативно тестировать этот запрос на продуктивных данных и сразу же вносить в него корректировки без переноса кода. Этот инструмент дал бы возможность при разработке использовать в коде ABAP-разработки уже полностью протестированный запрос.
Я решил заняться поиском такого инструмента.
Существующие инструменты
Я рассмотрел существующие инструменты SAP по работе с таблицами, в поисках такого, который помог бы с тестированием произвольных запросов в продуктивной системе, – у всех были те или иные недостатки (Рис. 3):
Рис. 3. Недостатки существующих инструментов
- Транзакция SE16/SE16N
- Можно делать выборку только из одной таблицы. Не подходит для запросов с несколькими таблицами.
- Транзакция ST04 (Additional functions -> SQL Command Editor)
- Во-первых, воспринимает только Native SQL-запросы (синтаксис СУБД), что накладывает некоторые неудобства, так как при разработке программ на ABAP для универсальности используются Open SQL-запросы, отличающиеся синтаксисом. Это, впрочем, можно было бы «пережить», если бы не «во-вторых».
- Во-вторых, работает только в том случае, если в качестве СУБД используется Oracle.
- Транзакция SQVI
- Нельзя соединять таблицы по не ключевым полям.
- Нельзя составлять запросы с подзапросами.
- Не отражается текст запроса. Выборка настраивается графически.
Готовые Z-разработки, найденные в интернете, тоже не подходили по различным причинам. В основном, из-за каких-либо существенных ограничений.
В итоге, не найдя подходящего готового инструмента, я решили разработать его сам.
Разрабатываем
Для начала в транзакции SE80 создаем программу ZSQL, GUI-статус MAIN100 с кнопкой «Выполнить» и Экран 0100.
Укрупнённо алгоритм программы выглядит так (Рис. 4):
Рис. 4. Алгоритм программы
Считывание SQL-запроса
Для получения SQL-запроса будем использовать текстовый редактор, который создадим на экране с помощью класса CL_GUI_TEXTEDIT. Для этого добавим на Экран 0100 пустой контейнер с именем MYEDIT, в который будем выводить редактор.
Фрагмент кода, создающий текстовый редактор на экране:
==================
data: g_editor type ref to cl_gui_textedit,
g_editor_container type ref to cl_gui_custom_container.
if g_editor is initial.
create object g_editor_container
exporting
container_name = `MYEDIT`
exceptions
cntl_error = 1
cntl_system_error = 2
create_error = 3
lifetime_error = 4
lifetime_dynpro_dynpro_link = 5.
create object g_editor
exporting
parent = g_editor_container
wordwrap_mode = cl_gui_textedit=>wordwrap_at_fixed_position
wordwrap_to_linebreak_mode = cl_gui_textedit=>true
exceptions
others = 1.
if sy-subrc <> 0.
leave program.
endif.
endif.
==================
Проверка на допустимый ввод
Введенный запрос необходимо проверить, чтобы исключить возможность выполнения UPDATE / DELETE / INSERT запросов и прочих опасных конструкций. Разрешаем только выполнения SELECT-запросов.
Фрагмент кода, проверяющий запрос:
==================
" Запрещенные слова/символы
"
data: lt_not_allowed_word type ty_simple_tab,
lt_parsed_sql_line type ty_simple_tab,
l_error_text(255) type c value 'Вы используете запрещенное слово или символ: '.
field-symbols: <fs_sql_query> type ty_simple_struc,
<fs_not_allowed_word> type ty_simple_struc,
<fs_parsed_sql_line> type ty_simple_struc.
append `UPDATE` to lt_not_allowed_word.
append `INSERT` to lt_not_allowed_word.
append `DELETE` to lt_not_allowed_word.
append `MODIFY` to lt_not_allowed_word.
append `CALL` to lt_not_allowed_word.
append `PERFORM` to lt_not_allowed_word.
append `COMMIT` to lt_not_allowed_word.
append `INCLUDE` to lt_not_allowed_word.
append `DROP` to lt_not_allowed_word.
append `ALTER` to lt_not_allowed_word.
append `.` to lt_not_allowed_word.
append `"` to lt_not_allowed_word.
"
loop at lt_sql_query assigning <fs_sql_query>.
" Первым словом первой строки должен быть SELECT
"
if sy-tabix = 1.
refresh lt_parsed_sql_line.
split <fs_sql_query>-line at space into table lt_parsed_sql_line.
delete lt_parsed_sql_line where line = ''.
read table lt_parsed_sql_line assigning <fs_parsed_sql_line> index 1.
translate <fs_parsed_sql_line>-line to upper case.
if <fs_parsed_sql_line>-line <> 'SELECT'.
message 'Запрос должен начинаться с SELECT' type 'I'.
l_error = 'X'.
exit.
endif.
endif.
" Проверяем на запрещенные слова
"
loop at lt_not_allowed_word assigning <fs_not_allowed_word>.
find <fs_not_allowed_word>-line in <fs_sql_query>-line ignoring case.
if sy-subrc = 0.
concatenate l_error_text ` ` <fs_not_allowed_word>-line into l_error_text.
message l_error_text type 'I'.
l_error = 'X'.
exit.
endif.
endloop.
endloop.
==================
Парсинг SQL-запроса
Из введенного SQL-запроса нам необходимо получить список выбираемых полей и таблиц для того, чтобы в дальнейшем на основании этого списка динамически сгенерировать структуру ALV-Grid для вывода результата.
Фрагмент кода, анализирующий запрос:
==================
types: ty_simple_tab type standard table of ty_simple_struc.
types: ty_t_code type standard table of rssource-line.
data lt_sql_query type ty_simple_tab.
lt_fields type ty_simple_tab,
lt_tables type ty_simple_tab,
l_use_cnt(1) type c.
" Анализируем запрос построчно
loop at lt_sql_query assigning <fs_sql_query>.
" Удаляем нечитаемые спец-символы
replace all occurrences of con_tab in <fs_sql_query>-line with space.
concatenate ` ` <fs_sql_query>-line ` ` into <fs_sql_query>-line.
" Разбиваем строку на отдельные слова
refresh lt_parsed_sql_line.
split <fs_sql_query>-line at space into table lt_parsed_sql_line.
delete lt_parsed_sql_line where line = ''.
loop at lt_parsed_sql_line assigning <fs_parsed_sql_line>.
translate <fs_parsed_sql_line>-line to upper case.
if <fs_parsed_sql_line>-line = 'SELECT'.
continue.
endif.
" Если дошли до * - считаем, что все выбираемые поля получены
if <fs_parsed_sql_line>-line = '*'.
l_field_names_obtained = 'X'.
continue.
endif.
" Если дошли до FROM или JOIN - считаем, что все выбираемые поля получены.
" Следующее слово будет названием таблицы
if <fs_parsed_sql_line>-line = 'FROM' or <fs_parsed_sql_line>-line = 'JOIN'.
l_field_names_obtained = 'X'.
l_is_tabname = 'X'.
continue.
endif.
" Получаем названия полей
if l_field_names_obtained is initial.
" Ищем конструкцию COUNT()
find 'COUNT(' in <fs_parsed_sql_line>-line ignoring case.
if sy-subrc = 0.
l_use_cnt = 'X'.
continue.
endif.
" Название поля указано с названием таблицы через ~
search <fs_parsed_sql_line>-line for '~'.
if sy-subrc = 0.
add 1 to sy-fdpos.
endif.
append <fs_parsed_sql_line>-line+sy-fdpos to lt_fields.
endif.
" Получаем названия таблиц
if l_is_tabname = 'X'.
append <fs_parsed_sql_line>-line to lt_tables.
clear l_is_tabname.
endif.
endloop.
endloop.
==================
Выполнение SQL-запроса
Чтобы выполнить наш запрос, воспользуемся оператором generate subroutine pool, который позволяет динамически генерировать временные ABAP-программы на основании переданного в качестве параметра исходного кода, которым мы подготовим из введенного SQL-запроса.
Фрагмент кода, генерирующий ABAP-программу:
==================
types: ty_t_code type standard table of rssource-line.
data: code type ty_t_code,
prog(8) type c,
msg(120) type c,
lt_parsed_sql_line type ty_simple_tab,
l_sub_order(1) type c.
field-symbols: <fs_sql_query> type ty_simple_struc,
<fs_parsed_sql_line> type ty_simple_struc.
append `program z_sql.` to code.
append `form get_data using fs_data type standard table.` to code.
append `try.` to code.
loop at lt_sql_query assigning <fs_sql_query>.
clear: lt_parsed_sql_line.
split <fs_sql_query>-line at space into table lt_parsed_sql_line.
delete lt_parsed_sql_line where line = ''.
loop at lt_parsed_sql_line assigning <fs_parsed_sql_line>.
concatenate ` ` <fs_parsed_sql_line>-line ` ` into <fs_parsed_sql_line>-line.
translate <fs_parsed_sql_line>-line to upper case.
" добавляем into… только 1 раз, иначе будет добавляться во все подзапросы
if <fs_parsed_sql_line>-line = ' FROM ' and l_sub_order is initial.
append `into corresponding fields of table fs_data` to code.
l_sub_order = 'X'.
endif.
append <fs_parsed_sql_line>-line to code.
endloop.
endloop.
append `.` to code.
append `rollback work.` to code.
append `catch cx_root.` to code.
append `rollback work.` to code.
append `message ``Что-то пошло не так, проверьте запрос`` type ``i``.` to code.
append `endtry.` to code.
append `endform.` to code.
generate subroutine pool code name prog
message msg.
==================
Вывод результата на экран
Так как состав полей и их тип нам заранее неизвестны, то для получения результата и вывода его на экран нам необходимо динамически сгенерировать внутреннюю таблицу и структуру ALV-Grid на основании выбираемых в запросе полей. Для этого будем использовать метод create_dynamic_table класса cl_alv_table_create.
Фрагмент кода, генерирующий структуру ALV-Grid:
==================
data: ref_table_descr type ref to cl_abap_structdescr,
lt_tab_struct type abap_compdescr_tab,
ls_fieldcatalog type slis_fieldcat_alv.
field-symbols: <fs_tab_struct> type abap_compdescr,
<fs_tables> type ty_simple_struc,
<fs_fields> type ty_simple_struc.
loop at lt_tables assigning <fs_tables>.
refresh lt_tab_struct.
" Получаем все поля для выбираемой таблицы
ref_table_descr ?= cl_abap_typedescr=>describe_by_name( <fs_tables>-line ).
lt_tab_struct[] = ref_table_descr->components[].
loop at lt_tab_struct assigning <fs_tab_struct>.
" если поля нет среди выбираемых в SQL-запросе - не выводим его не экран
if lines( lt_fields ) > 0.
read table lt_fields transporting no fields with key line = <fs_tab_struct>-name.
if sy-subrc <> 0.
continue.
endif.
endif.
" если поле с таким именем уже есть, то не добавляем повторно
read table lt_fieldcatalog transporting no fields with key fieldname = <fs_tab_struct>-name.
if sy-subrc = 0.
continue.
endif.
clear ls_fieldcatalog.
ls_fieldcatalog-fieldname = <fs_tab_struct>-name.
ls_fieldcatalog-ref_tabname = <fs_tables>-line.
append ls_fieldcatalog to lt_fieldcatalog.
endloop.
endloop.
" В запросе есть конструкция COUNT() – добавляем колонку с именем CNT и типом INT
if l_use_cnt = 'X'.
clear ls_fieldcatalog.
ls_fieldcatalog-fieldname = 'CNT'.
ls_fieldcatalog-seltext_l = 'Кол-во'.
ls_fieldcatalog-seltext_m = 'Кол-во'.
ls_fieldcatalog-seltext_s = 'Кол-во'.
ls_fieldcatalog-datatype = 'INT4'.
if p_tech_names = 'X'.
ls_fieldcatalog-seltext_l = 'CNT'.
ls_fieldcatalog-seltext_m = 'CNT'.
ls_fieldcatalog-seltext_s = 'CNT'.
ls_fieldcatalog-reptext_ddic = 'CNT'.
endif.
append ls_fieldcatalog to lt_fieldcatalog.
endif.
==================
Фрагмент кода, создающий динамическую таблицу:
==================
data: dyn_table type ref to data,
dyn_line type ref to data,
lt_lvc_fieldcatalog type lvc_t_fcat,
ls_lvc_fieldcatalog type lvc_s_fcat.
field-symbols: <fs_fieldcatalog> type slis_fieldcat_alv.
" Преобразуем данные в другой тип
loop at lt_fieldcatalog assigning <fs_fieldcatalog>.
clear ls_lvc_fieldcatalog.
move-corresponding <fs_fieldcatalog> to ls_lvc_fieldcatalog.
ls_lvc_fieldcatalog-ref_table = <fs_fieldcatalog>-ref_tabname.
append ls_lvc_fieldcatalog to lt_lvc_fieldcatalog.
endloop.
" Создаем динамически таблицу
call method cl_alv_table_create=>create_dynamic_table
exporting
it_fieldcatalog = lt_lvc_fieldcatalog
importing
ep_table = dyn_table.
assign dyn_table->* to <fs_data>.
create data dyn_line like line of <fs_data>.
assign dyn_line->* to <fs_wa_data>.
==================
Полный листинг исходного кода программы ZSQL:
==================
type-pools: slis.
types: begin of ty_simple_struc,
line(255) type c,
end of ty_simple_struc.
types: ty_simple_tab type standard table of ty_simple_struc.
types: ty_t_code type standard table of rssource-line.
data: g_editor type ref to cl_gui_textedit,
g_editor_container type ref to cl_gui_custom_container,
g_ok_code like sy-ucomm,
p_tech_names(1) type c.
field-symbols: <fs_data> type standard table,
<fs_wa_data> type any.
call screen 100.
module pbo output.
set pf-status `MAIN100`.
" Выводим на форму текстовый редактор для SQL-запроса
if g_editor is initial.
create object g_editor_container
exporting
container_name = `MYEDIT`
exceptions
cntl_error = 1
cntl_system_error = 2
create_error = 3
lifetime_error = 4
lifetime_dynpro_dynpro_link = 5.
create object g_editor
exporting
parent = g_editor_container
wordwrap_mode = cl_gui_textedit=>wordwrap_at_fixed_position
wordwrap_to_linebreak_mode = cl_gui_textedit=>true
exceptions
Если хотите прочитать статью полностью и оставить свои комментарии присоединяйтесь к sapland
ЗарегистрироватьсяУ вас уже есть учетная запись?
Войти
Обсуждения 19
Комментарий от
Анатолий Халимовский
| 14 января 2016, 17:55
Комментарий от
Николай Кронский
| 15 января 2016, 13:03
Анатолий Халимовский 14 января 2016, 17:55
8-/ В системе безопасности появилась "черная дыра"...
Согласен, виден подход программиста но не разработчика...
Комментарий от
Руслан Закарьяев
| 15 января 2016, 16:39
Николай Кронский 15 января 2016, 13:03
Толя, привет.
Согласен, виден подход программиста но не разработчика...
Я в статье специально не затрагивал вопросы, связанные с организацией доступа к этому инструменту и данным, потому что, во-первых, основной целью статьи было все таки показать функциональность инструмента; во-вторых, на разных проектах могут быть разные требования к уровню доступа к данным: где-то достаточно ограничить доступ к программе, где-то к таблице, а где-то к конкретным записям таблицы.
С точки зрения функциональности этот инструмент не дает большего объема информации, чем, скажем, транзакция SE16N.
Комментарий от
Олег Точенюк
| 16 января 2016, 15:17
Для вывода результата выборки, если необходимо, пишется один ФМ куда передается объявленная таблица, и который в свою очередь, выводит любую таблицу в отдельном всплывающем окне используя вот эти 4 строки:
DATA: gc_alv_table TYPE REF TO cl_salv_table.
cl_salv_table=>factory( IMPORTING r_salv_table = gc_alv_table
CHANGING t_table = lt_ekko[] ).
gc_alv_table->display( ).
В предложенном редакторе можно вбивать не только запросы SQL, но и объявлять свои переменные, подпрограммы и т.д. вызывать модули и создавать классы.
В общем тоже можно сказать черная дыра, но правда, возможность ввода кода в окна, управляется полномочиями. Опять же можем параллельно проверять производительность участков кода с небольшими изменениями.
PS: Что касается еще так называемой черной дыры, ну если у вас абаперы так свободно бегают в тестовую среду с реальными данными, то что вам мешает или скопировать эти данные в соседний мандант системы разработки (верю что тут может быть мало места) или открыть в системе теста возможность создавать локальные программы и уже там, в стандартном SE38, быстро моделировать работу с данными?
Комментарий от
Олег Точенюк
| 16 января 2016, 16:00
Олег Точенюк 16 января 2016, 15:17
Для проверки своих запросов,особенно если есть различные варианты, следует воспользоваться транзакцией SE38: на первом экране нужно перейти по меню: Среда – Примеры – Примеры производительности.
Для вывода результата выборки, если необходимо, пишется один ФМ куда передается объявленная таблица, и который в свою очередь, выводит любую таблицу в отдельном всплывающем окне используя вот эти 4 строки:
DATA: gc_alv_table TYPE REF TO cl_salv_table.
cl_salv_table=>factory( IMPORTING r_salv_table = gc_alv_table
CHANGING t_table = lt_ekko[] ).
gc_alv_table->display( ).
В предложенном редакторе можно вбивать не только запросы SQL, но и объявлять свои переменные, подпрограммы и т.д. вызывать модули и создавать классы.
В общем тоже можно сказать черная дыра, но правда, возможность ввода кода в окна, управляется полномочиями. Опять же можем параллельно проверять производительность участков кода с небольшими изменениями.
PS: Что касается еще так называемой черной дыры, ну если у вас абаперы так свободно бегают в тестовую среду с реальными данными, то что вам мешает или скопировать эти данные в соседний мандант системы разработки (верю что тут может быть мало места) или открыть в системе теста возможность создавать локальные программы и уже там, в стандартном SE38, быстро моделировать работу с данными?
Комментарий от
Михаил Кирилловский
| 17 января 2016, 16:35
Комментарий от
Руслан Закарьяев
| 18 января 2016, 13:06
Олег Точенюк 16 января 2016, 16:00
Ну т.е. на выходе получается что-то типа такого
Способ, который вы описАли, имеет два существенных недостатка:
1. Нет никакой фильтрации введенного кода - это действительно самая настоящая черная дыра. Можно выполнить абсолютно любой АБАП-код, включая UPDATE/DELETE.
2. Самое главное. Данный инструмент можно использовать только в той системе, в которой мы можем редактировать код программ. Он не работает, если у системы стоит статус "Неизменяемая". А такой статус стоит у любой продуктивной и тестовой системы. Т.е. теряется вообще вся идея и весь смысл.
Скопировать реальные данные в систему разработки не представляется возможным по двум причинам:
1. Вы правы: нет места.
2. Из соображений безопасности. В продуктивной и тестовой системах доступ к данным можно контролировать полномочиями, а в системе разработки проверки полномочий обходятся на раз-два.
Разрешать в тестовой системе писать код тоже не представляется возможным. Может, в каких-то проектах это практикуется. В наших - нет.
Комментарий от
Руслан Закарьяев
| 18 января 2016, 13:07
Михаил Кирилловский 17 января 2016, 16:35
А с чего вы взяли, что в ST04 SQL editor заточен исключительно под ORACLE? В среде с DB2 тоже все превосходно работает.
Взял с того, что для DB2 пункта Additional functions -> SQL Command Editor в ST04 нет. В многочисленных ветках на scn.sap.com говорится то же самое.
Вы знаете какой-то другой способ? Поделитесь, пожалуйста.
Комментарий от
Михаил Сидорочкин
| 18 января 2016, 14:13
Руслан Закарьяев 18 января 2016, 13:07
Добрый день.
Взял с того, что для DB2 пункта Additional functions -> SQL Command Editor в ST04 нет. В многочисленных ветках на scn.sap.com говорится то же самое.
Вы знаете какой-то другой способ? Поделитесь, пожалуйста.
Комментарий от
Михаил Кирилловский
| 18 января 2016, 18:34
Руслан Закарьяев 18 января 2016, 13:07
Добрый день.
Взял с того, что для DB2 пункта Additional functions -> SQL Command Editor в ST04 нет. В многочисленных ветках на scn.sap.com говорится то же самое.
Вы знаете какой-то другой способ? Поделитесь, пожалуйста.
Плохо ищите.
Комментарий от
Руслан Закарьяев
| 19 января 2016, 18:02
Михаил Кирилловский 18 января 2016, 18:34
ST04 -> Diagnostics -> SQL Command line
Плохо ищите.
Ладно, это была не суть статьи. В любом случае, ST04 не подходит из-за Native SQL.
Комментарий от
Олег Точенюк
| 20 января 2016, 17:56
Руслан Закарьяев 18 января 2016, 13:06
Добрый день.
Способ, который вы описАли, имеет два существенных недостатка:
1. Нет никакой фильтрации введенного кода - это действительно самая настоящая черная дыра. Можно выполнить абсолютно любой АБАП-код, включая UPDATE/DELETE.
2. Самое главное. Данный инструмент можно использовать только в той системе, в которой мы можем редактировать код программ. Он не работает, если у системы стоит статус "Неизменяемая". А такой статус стоит у любой продуктивной и тестовой системы. Т.е. теряется вообще вся идея и весь смысл.
Скопировать реальные данные в систему разработки не представляется возможным по двум причинам:
1. Вы правы: нет места.
2. Из соображений безопасности. В продуктивной и тестовой системах доступ к данным можно контролировать полномочиями, а в системе разработки проверки полномочий обходятся на раз-два.
Разрешать в тестовой системе писать код тоже не представляется возможным. Может, в каких-то проектах это практикуется. В наших - нет.
2. А вас с вашей программой в продуктивную систему пускают? Код редактировать не обязательно, статус системы должен быть не блокированная, полномочия на разработку иметь вроде как не обязательно, добавить разве что надо что-то типа такого:
authority-check object 'S_DEVELOP'
id 'OBJTYPE' field 'PROG'
id 'DEVCLASS' dummy
id 'P_GROUP' dummy
id 'OBJNAME' dummy
id 'ACTVT' field '02'.
3. Ваша программа выбирает данные из таблиц, в тестовой системе которая, где-то равна продуктивной. Тогда о какой безопасности данных мы говорим? Кто помешает вашей разработкой считать данные из любых таблиц? Так что безопасность что тут что там, как сферический код в вакууме.
Комментарий от
Руслан Закарьяев
| 21 января 2016, 12:30
Олег Точенюк 20 января 2016, 17:56
1. Нет такого конечно, но вы то сами делаете разработку, которая с точки зрения системы не совсем кошерная. Далее работать предполагается в системе теста, так что если и удалят что-то то вряд ли это критично-критично. Зато код может быть написан разный + можно быстро проверить скорость выполнения кода при разных модификациях.
2. А вас с вашей программой в продуктивную систему пускают? Код редактировать не обязательно, статус системы должен быть не блокированная, полномочия на разработку иметь вроде как не обязательно, добавить разве что надо что-то типа такого:
authority-check object 'S_DEVELOP'
id 'OBJTYPE' field 'PROG'
id 'DEVCLASS' dummy
id 'P_GROUP' dummy
id 'OBJNAME' dummy
id 'ACTVT' field '02'.
3. Ваша программа выбирает данные из таблиц, в тестовой системе которая, где-то равна продуктивной. Тогда о какой безопасности данных мы говорим? Кто помешает вашей разработкой считать данные из любых таблиц? Так что безопасность что тут что там, как сферический код в вакууме.
2/3. Да, нашу программу пускают. Конечно, не в том виде, в котором она описана в статье. У нас есть проверка полномочий: доступ к таблицам и даже к отдельным записям ограничен - никаких лишних данных никто не получит.
Ваш инструмент тоже очень полезен, но он предназначен немного для других целей.
Комментарий от
Шахин Микаилов
| 02 февраля 2016, 11:55
Интересная статья.
Мы для таких вещей используем Hovitaga Report Generator. Многофункционально, легько установит, использоват и главное безопасно.
Комментарий от
Антон Сорокин
| 02 февраля 2016, 12:56
Не, ну как же. В se16n нет join, это очень существенно. Join - это единственное и главное чего не хватает для удобных выборок.
Забавные заказчики, которые пускают это в продуктив :) В моей практике и se16n не всегда можно запустить :)
Комментарий от
Анатолий Халимовский
| 12 февраля 2016, 15:48
Антон Сорокин 02 февраля 2016, 12:56
>>С точки зрения функциональности этот инструмент не дает большего объема информации, чем, скажем, транзакция SE16N.
Не, ну как же. В se16n нет join, это очень существенно. Join - это единственное и главное чего не хватает для удобных выборок.
Забавные заказчики, которые пускают это в продуктив :) В моей практике и se16n не всегда можно запустить :)
Возможности расписаны в 1636416 - CO-OM tools: Functions of transaction SE16H
Комментарий от
Юрий Сычов
| 16 мая 2016, 21:59
zaaqb - sql query tool
sapnet.ru/viewtopic.php
Комментарий от
Юлия Матченко
| 30 мая 2016, 10:10
Олег Точенюк 16 января 2016, 15:17
Для проверки своих запросов,особенно если есть различные варианты, следует воспользоваться транзакцией SE38: на первом экране нужно перейти по меню: Среда – Примеры – Примеры производительности.
Для вывода результата выборки, если необходимо, пишется один ФМ куда передается объявленная таблица, и который в свою очередь, выводит любую таблицу в отдельном всплывающем окне используя вот эти 4 строки:
DATA: gc_alv_table TYPE REF TO cl_salv_table.
cl_salv_table=>factory( IMPORTING r_salv_table = gc_alv_table
CHANGING t_table = lt_ekko[] ).
gc_alv_table->display( ).
В предложенном редакторе можно вбивать не только запросы SQL, но и объявлять свои переменные, подпрограммы и т.д. вызывать модули и создавать классы.
В общем тоже можно сказать черная дыра, но правда, возможность ввода кода в окна, управляется полномочиями. Опять же можем параллельно проверять производительность участков кода с небольшими изменениями.
PS: Что касается еще так называемой черной дыры, ну если у вас абаперы так свободно бегают в тестовую среду с реальными данными, то что вам мешает или скопировать эти данные в соседний мандант системы разработки (верю что тут может быть мало места) или открыть в системе теста возможность создавать локальные программы и уже там, в стандартном SE38, быстро моделировать работу с данными?
Комментарий от
Олег Точенюк
| 30 мая 2016, 13:46
Юлия Матченко 30 мая 2016, 10:10
Олег, у меня в тр.se38 нет возможности вставлять свой текст. Не подскажете, где это можно настроить?
CALL METHOD CODE_LEFT_EDITOR->SET_READONLY_MODE
EXPORTING
READONLY_MODE = 1.
И никакой проверки полномочий. Так что данный способ можно сказать закрыт, хотя никто не мешает вам скопировать программу RSHOWTIM в свою и там разрешить редактирование, для внутреннего так сказать использования. Предлагать в энхансменте менять READONLY_MODE = 0, не буду. А то придет Василий и будет сильно расстроен :-)