:::: МЕНЮ ::::

Заполнение справочных полей таблицы по ключу

Пусть у нас имеется внутренняя таблица, размерность которой может составлять как десяток строк, так и сотни тысяч строк

Поля таблицы можно классифицировать на справочные и не справочные. К первой группе относятся: bukrs_txt, werks_txt, matnr_txt. Ко второй остальные. Для каждого справочного поля имеется соответствующий ключ, по которому можно однозначно определить значение справочного поля. Например, ключом поля bukrs_txt будет bukrs, т.к. для определения наименования БЕ необходимо знать код БЕ. Как правило, заполнение справочных полей значениям происходит в последнюю очередь.
Задача: заполнить справочные поля по соответствующим ключам, используя при этом минимальные ресурсные затраты.

Данная задача является типичной для MM и FI. Рассмотрим наиболее популярные способы ее решения.

Способ 1

Самый простой вариант — для каждой строке в цикле вызвать SELECT SINGLE.

На практике данный вариант можно применить в двух случаях:

  1. Таблица небольшого размера
  2. Число уникальных ключей равно (или почти равно) числу строк таблицы

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

Способ 2

Для каждого ключевого поля выбрать все уникальные значения, затем в базе данных выбрать все справочные значения по данным ключам, далее подставить их в исходную таблицу. Пример реализации для заполнения наименования БЕ.

Данный метод хорош и многим программистам он предпочтителен. На habrahabr даже есть статья, описывающая технологию универсализизации данного метода. При использовании данного метода не забывайте проверять таблицу lt_tab на наличие по крайней мере одной записи, иначе программа будет перебирать все записи в БД. Если вы решите использовать универсальный метод по ссылке выше учите, что INSERT REPORT игрушка опасная и бдительный базис не пропустит ваш запрос в продуктив.

Способ 3

Аналогичный предыдущему, однако, отличающийся технологией сбора уникальных значений ключа. А именно, сначала формируется рендж уникальных значений, затем делается запрос в БД с передачей ренджа.

Данный метод работает немного быстрее предыдущего. Быстрота обуславливается тем, что конструкция FOR ALL ENTRIES IN разбивает запрос на несколько запросов и данные выбираются не все сразу, а частями.
Однако, стоит учитывать, что если рендж уникальных значений будет содержать большое чисто строк (1000+), то вы получите дамп DBIF_RSQL_INVALID_RSQL из-за того, что размер SQL-запроса превысит допустимую границу. Также необходимо проверять что рендж не пустой.

Способ 4

Похож на предыдущие два, отличается тем, что справочник уникальных значений собираем по мере необходимости. На каждую новую запись делаем SELECT SINGLE.

Быстродействие данного метода сравнимо с предыдущими двумя.

Что использовать на практике?

На практике я использую обертку над последним методом. По скорости, гибкости и универсальности он является самым оптимальным. А справочные данные позволяет брать не только из базы данный, но и на основе локальных переменных программы.

Пример универсальной процедуры.

И пример использования


Присоединиться к обсуждению...