Текущее время: Вс, июл 20 2025, 15:34

Часовой пояс: UTC + 3 часа


Правила форума


ВНИМАНИЕ!

Вопросы по SAP Query и Quick View - сюда



Начать новую тему Ответить на тему  [ Сообщений: 32 ]  На страницу Пред.  1, 2, 3
Автор Сообщение
 Заголовок сообщения:
СообщениеДобавлено: Пн, фев 19 2007, 12:52 
Младший специалист
Младший специалист

Зарегистрирован:
Пт, июн 02 2006, 09:59
Сообщения: 67
Пол: Мужской
Удав написал(а):
abap написал:
Рассмотрим ключ, состоящий из 4-х полей, например: WERKS, LGORT, MJAHR и наш ID.
Вопросы: 1. При чем тут NRIV, если я просто хочу увеличить суррогатный ключ ID на единичку? 2. Какие будут тормоза при определени max( ID ), если указать остальную часть ключа? 3. Как обойтись в системе, в которой работает больше одного пользователя без блокировок?

1.При одновременном обращении к select`у возможно появление 2-х одинаковых номеров. Что, соответственно, ведет к дампу при попытке вставки записи в таблицу.
2.см. п.3 - для правильного определения последнего номера необходимо блокировать ВСЮ часть таблицы по 3-м первым полям. Соответственно, если работает не один человек, то при получении номера он вынужден ждать, пока не снимется блокировка.
3. Если речь идет о получении нового номера, то с помощью механизма, предлагаемого SAP, который называется "Объекты нумерации". :wink:
Почитайте первоисточник.

Вещь базовая, поэтому важно полное понимание.
Рассмотрим вопрос более детально.
Итак, предлагался ключ: год/завод/склад/ID. Для связи с жизнью предположим, что мы хотим пишем модуль по созданию неких внутренних складских документов – назовем их Актами. Предположим далее, что у нас 10 заводов по 10 складов на каждом:
Завод 5000 Склад 5001, 5002, …, 5010
Завод 5100 Склад 5101, 5102, …, 5110

Завод 5900 Склад 5901, 5902, …, 5910
Воспользуемся нумератором и создадим последовательно (для простоты) по два Акта на каждом складе. Получим записи в нашей таблице (например, Z_TABLE)
с ключами (мандант не рассматриваем):
2007 5000 5001 0000000001
2007 5000 5001 0000000002
2007 5000 5002 0000000003
2007 5000 5002 0000000003

2007 5900 5910 0000000199
2007 5900 5910 0000000200

Вместо этого хотели:
2007 5000 5001 0000000001
2007 5000 5001 0000000002
2007 5000 5002 0000000001
2007 5000 5002 0000000002

2007 5900 5910 0000000001
2007 5900 5910 0000000002
Даже использование в качестве subobject в function 'NUMBER_GET_NEXT', например, завода все равно проблему не решит, т.е. придется либо создавать по одному нумератору на завод либо мириться с «рваной» нумерацией на складе. (Правда, возможно, прокатит создать и использовать в качестве subobject 8-ми-байтный домен, в качестве значения которого брать конкатенацию завода/склада – не знаю, сам не пробовал).
Далее. Предположим, создается очередной Акт, на заводе 5900/ складе 5910. Ну и что криминального в том, что перед получением очередного номера(ID) на этом складе, мы заблокируем запись по ключу 2007 5900 5910 ? Как говорится, в этом нет никакого вреда, кроме пользы. Для этого технология блокирования и существует.
Более того. Предположим даже такой вариант, что мы поставлены в условия, когда блокировать склад недопустимо (например, кладовщик Вася имеет привычку открывать транзакцию создания Акта и уходить на перекур, а кладовщик Петя сильно нервничает в этот момент при виде сообщения: «Запрошенный объект сейчас блокирован пользователем Васей»). В этом случае наши действия меняются совсем незначительно: получаем следующий ID (max по году/заводу/складу); ставим блокировку по полному ключу (году/заводу/складу/maxID+1); селектим еще раз таблицу по году/заводу/складу/maxID+1 в качестве лекарства от дампов, далее делаем свой INSERT;
далее снимаем блокировку.
Именно такая технология используется, например, в многострадальной SAPMF05A, где кстати в силу простоты ключа используется именно нумератор (RF_BELEG). Заглянем в ФМ ‘RF_GET_DOCUMENT_NUMBER’. Видим, что после получения очередного номера по БЕ в качестве subobject, могучие программисты SAP все-таки делают проверку на существование записи с таким ключом в BKPF. Интересно зачем? Ах да, о чем это я... Да вот же и ответ!

Code:
*------- Beleg probelesen ----------------------------------------------
  select single belnr into bkpf-belnr from bkpf
         where bukrs = company
         and   belnr = document_number
         and   gjahr = year.
  if sy-subrc is initial.
*
* Belegnummer & & & wurde bereits vergeben
*
    message a152 with company document_number year
                 range                                      "Note449030
                 raising duplicate_number.
  endif.

что в переводе с ломанного немецкого: "oops, а номерок уже использован - поэтому ABEND". Подумаешь, юзер перед этим долбил 20 позиций в документ...
Вот тебе и SAP best practices..


Принять этот ответ
Вернуться к началу
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: Пн, фев 19 2007, 16:10 
Почетный гуру
Почетный гуру
Аватара пользователя

Зарегистрирован:
Чт, окт 06 2005, 16:44
Сообщения: 3080
Откуда: Москва
Ну как сказать...
Начнем с кода SAP.
1. В ноте 449030 - FB01: Switch off number range buffering on interval level сказано, что она применима ТОЛЬКО В СЛУЧАЕ, когда есть проблема с производительностью при присвоении номеров.
Цитата:
Caution: If the 'No buffering' setting does not negatively affect performance, you do not need to take this into account and do not have to take any action!.

В случае многопользовательской работы, как я уже говорил, использование select max( number ) намного медленнее, чем select single ... from nriv.

Особенно, если использовать локальные копии NRIV :)

В ноте указано
Цитата:
"Identify the combinations of company code, number range (belonging to document type/business transaction) and fiscal year for which you absolutely need a chronologically ascending sequence. (Experience has shown that a chronologically ascending sequence is not necessary for all business transactions)."


2.Можно посмотреть кучу других примеров по использованию NUMBER_GET_NEXT - посмотрите журнал использования. Проведите статистику, если уж привели пример с RF_GET_DOCUMENT_NUMBER: какой процент программ после вызова NUMBER_GET_NEXT проверяет, есть ли запись с таким ключом в искомой таблице? :)


А программисты, писавшие 'RF_GET_DOCUMENT_NUMBER', действительно "могучие". К сожалению, в SAP таких хватает. :cry:

Продолжим с Вашим примером:
Цитата:
получаем следующий ID (max по году/заводу/складу); ставим блокировку по полному ключу (году/заводу/складу/maxID+1); селектим еще раз таблицу по году/заводу/складу/maxID+1 в качестве лекарства от дампов, далее делаем свой INSERT;

1.А как быть с многопользовательской работой, когда номера документов должны создаваться в ХРОНОЛОГИЧЕСКОМ порядке (следуем тексту ноты 449030)?
В Вашем случае получится следующее:
Предположим, что текущий номер записи - 9
а)Вася открыл транзакцию создания бухгалтерского документа.
Блокировался номер 10.
б)Петя открыл транзакцию создания бухгалтерского документа.
Блокировался номер 11.

и тут 2 варианта:
-Вася решил не заводить бухгалтерский документ, а Петя завел. В результате документа с номером 10 в системе не будет. Понятно, что это "лечится" с помощью блокировки и присвоения номера непосредственно перед записью
-Света решила завести бухгалтерский документ. Что будет? :)


И наконец, что делать со сложными ключами:
1.Конкатенация сложного ключа в строку. Ведение всех возможных комбинаций на уровне подобъекта. Можно, но не очень удобно в ведении и не очень информативно.

2.Конкатерировать сложный ключ из префикса и ключевых полей (до собственно номера) и сделать его не подобъектом, а объектом нумерации. То есть для каждой комбинации завод-склад сделать свой объект нумерации. Ведение объектов нумерации возможно в автоматическом режиме через группу функций SNR2

3.Завести настроечную таблицу BUKRS, WERKS, NRRANGENR (Номер диапазона объекта номеров) и перед определением номера определять, какой диапазон использовать для комбинации BUKRS-WERKS. Как пример - для тех же бухгалтерских документов используется настройка видов бух.документов - таблица T003.

_________________
С уважением,
Удав.


Принять этот ответ
Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 32 ]  На страницу Пред.  1, 2, 3

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB