Текущее время: Пн, дек 22 2025, 05:28

Часовой пояс: 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 часа


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

Сейчас этот форум просматривают: Google [Bot]


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

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