AXForum  
Вернуться   AXForum > Microsoft Dynamics NAV > NAV: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 21.11.2011, 11:20   #1  
Predatore is offline
Predatore
Участник
 
163 / 17 (1) ++
Регистрация: 29.09.2010
Доброго времени суток!
Я вот столкнулся с задачей, решение которой мне не приходит на ум. Может его и вовсе нет, но я надеюсь что это не так.
Суть: идёт импорт данных, во время импорта естественно идут всяческие проверки и если что не так, то вываливаемся в ERROR. По ходу импорта ведётся его лог, куда, чего, откуда и на какой стадии. В этот же лог хотелось бы записать и ошибку, если таковая произойдёт. Вот тут и вопрос: как это сделать? Ведь ERROR отменяет все действия, поэтому то что я запишу в таблицу лога тоже будет отменено.
Старый 21.11.2011, 11:27   #2  
DA_NEAL is offline
DA_NEAL
Участник
Аватар для DA_NEAL
Лучший по профессии 2017
Лучший по профессии 2009
 
788 / 54 (3) ++++
Регистрация: 05.08.2002
Адрес: Королев
Пиши в текстовой файл или COMMIT таблицы лога.
__________________
Want to believe...
Старый 21.11.2011, 11:39   #3  
Predatore is offline
Predatore
Участник
 
163 / 17 (1) ++
Регистрация: 29.09.2010
Цитата:
Сообщение от DA_NEAL Посмотреть сообщение
Пиши в текстовой файл или COMMIT таблицы лога.
Писать в текстовый файл, об этом я думал, но когда я скину данные из файла в лог? А мне эти данные по зарез нужны в логе. Причём лог мне нужен актуальный. В общем через текстовый файл, это конечно решение, но очень уж корявое. А вот про COMMIT таблицы лога, можно по подробней, разве COMMIT не всю БД коммитит?
Старый 21.11.2011, 13:22   #4  
zm is offline
zm
Участник
 
44 / 10 (1) +
Регистрация: 15.07.2003
Адрес: Латвия
Все Errors (в смысле все ситуации кот. вызывают Error)вынести в отдельный CU50xxx. Использовать if CU50xxx.run Then...
Else WriteLogFile(,,,GETLASTERRORTEXT,..)
Старый 21.11.2011, 13:38   #5  
InTacto is offline
InTacto
Участник
Аватар для InTacto
 
323 / 11 (1) +
Регистрация: 09.08.2005
Занимаюсь сейчас похожей задачей. Все изменения в базу заношу только после всех проверок, это позволяет не порождать Error, для отмены транзакции. Все Error'ы заменил на message.
Правда, если что-то не штатное, то систему не поборешь.
Старый 21.11.2011, 13:50   #6  
InTacto is offline
InTacto
Участник
Аватар для InTacto
 
323 / 11 (1) +
Регистрация: 09.08.2005
Цитата:
Сообщение от zma Посмотреть сообщение
Все Errors (в смысле все ситуации кот. вызывают Error)вынести в отдельный CU50xxx. Использовать if CU50xxx.run Then...
Else WriteLogFile(,,,GETLASTERRORTEXT,..)
а транзакция все равно отменится?
Старый 21.11.2011, 14:22   #7  
zm is offline
zm
Участник
 
44 / 10 (1) +
Регистрация: 15.07.2003
Адрес: Латвия
Да транзакция откатится, но в LogFile все можно отобразить.
Test1. => WriteLogfile(1),
Test2, => WriteLogfile(2),...
Commit;
If CU50xxx then..
else WriteLogFile(3);
Старый 21.11.2011, 14:53   #8  
Predatore is offline
Predatore
Участник
 
163 / 17 (1) ++
Регистрация: 29.09.2010
Если начать транзакцию до запуска кодеюнита в примере от zma, то в случае вызова ERROR выскочит ошибка выполнения (во время транзакции нельзя использовать CU.RUN с возвращаемым значением отличным от Ok). Т.е. надо попробовать переписать код так, что бы транзакция стартовала в случае удачного выполнения кодеюнита (IF CU50xx.RUN THEN). Это было бы не проблемой, если бы проверка была всего одна. Но если у меня десятки проверок, причём вложенных... И всё это уже написано и работает, тут я уже боюсь браться за подобную реализацию, лучше уж через файлы...
Пока писал, придумал что можно сделать. Фактически это вариация на тему того, что предложил InTacto. Пока разбираем входящие данные, пишем всё во временные таблицы (кроме Лога). При этом после каждой записи в Лог (или перед потенциальными вызовами ERROR) делаем COMMIT. Ну и в самом конце, сливаем данные из временных таблиц в обычные. В итоге у нас и ERROR нормально отработает и Лог запишется и данные никуда не попадут, если встретится хотя бы один ERROR.
Или ещё красивее. Делаем функцию LogError, которую вызываем вместо ERROR, в ней пишем в Лог всё что нужно, потом COMMIT, а потом ERROR. Теперь у нас COMMIT вызовется только перед ERROR, а не перед каждым потенциальным ERROR или после каждой записи в Лог.
Старый 21.11.2011, 16:02   #9  
alexb_imported is offline
alexb_imported
Участник
 
256 / 12 (1) ++
Регистрация: 25.08.2006
Цитата:
Сообщение от Predatore Посмотреть сообщение
В том то и засада, что транзакция не отменится, если быть ещё точнее, то если начать транзакцию до запуска кодеюнита, то в случае вызова ERROR выскочит ошибка выполнения (во время транзакции нельзя использовать CU.RUN с возвращаемым значением отличным от Ok). Т.е. надо попробовать переписать код так, что бы транзакция стартовала в случае удачного выполнения кодеюнита (IF CU50xx.RUN THEN). Это было бы не проблемой, если бы проверка была всего одна. Но если у меня десятки проверок, причём вложенных... тут я уже даже боюсь браться за подобную реализацию, лучше уж через файлы...
Пока писал, придумал что можно сделать. Фактически это вариация на тему того, что предложил InTacto. Пока разбираем входящие данные, пишем всё во временные таблицы (кроме Лога). При этом после каждой записи в Лог (или перед потенциальными вызовами ERROR) делаем COMMIT. Ну и в самом конце, сливаем данные из временных таблиц в обычные. В итоге у нас и ERROR нормально отработает и Лог запишется и данные никуда не попадут, если встретится хотя бы один ERROR.
Я пишу лог в зависимости от того, был ли при работе codeunit'a ERROR или нет таким образом:

Код:
CLEARLASTERROR;
textLoc := '';
COMMIT;

IF Codeunit5xxx.RUN() THEN;

textLoc := COPYSTR(GETLASTERRORTEXT,1,MAXSTRLEN(textLoc));
if  textLoc <> '' THEN BEGIN
  WriteLog(textLoc);
END;
Старый 21.11.2011, 16:34   #10  
Predatore is offline
Predatore
Участник
 
163 / 17 (1) ++
Регистрация: 29.09.2010
Цитата:
Сообщение от AlexB Посмотреть сообщение
Цитата:
Сообщение от Predatore Посмотреть сообщение
В том то и засада, что транзакция не отменится, если быть ещё точнее, то если начать транзакцию до запуска кодеюнита, то в случае вызова ERROR выскочит ошибка выполнения (во время транзакции нельзя использовать CU.RUN с возвращаемым значением отличным от Ok). Т.е. надо попробовать переписать код так, что бы транзакция стартовала в случае удачного выполнения кодеюнита (IF CU50xx.RUN THEN). Это было бы не проблемой, если бы проверка была всего одна. Но если у меня десятки проверок, причём вложенных... тут я уже даже боюсь браться за подобную реализацию, лучше уж через файлы...
Пока писал, придумал что можно сделать. Фактически это вариация на тему того, что предложил InTacto. Пока разбираем входящие данные, пишем всё во временные таблицы (кроме Лога). При этом после каждой записи в Лог (или перед потенциальными вызовами ERROR) делаем COMMIT. Ну и в самом конце, сливаем данные из временных таблиц в обычные. В итоге у нас и ERROR нормально отработает и Лог запишется и данные никуда не попадут, если встретится хотя бы один ERROR.
Я пишу лог в зависимости от того, был ли при работе codeunit'a ERROR или нет таким образом:

Код:
CLEARLASTERROR;
textLoc := '';
COMMIT;

IF Codeunit5xxx.RUN() THEN;

textLoc := COPYSTR(GETLASTERRORTEXT,1,MAXSTRLEN(textLoc));
if  textLoc <> '' THEN BEGIN
  WriteLog(textLoc);
END;
Спасибо за идею, хотя работоспособна она только от 5-ой версии и выше. В будущем может пригодится, а сейчас я уже сделал как выше описал, тем паче, у меня и так временные таблицы используются, и изменения пришлось внести минимальные.
Старый 22.11.2011, 07:58   #11  
rmv is offline
rmv
Участник
 
481 / 11 (1) +
Регистрация: 15.02.2005
Данные во временных таблицах не удаляются при откате транзакций. Создайте Single Instance кодеюнит и пишите лог во временную таблицу.
В базу буфер временной таблицы можно сбрасывать либо по событию (инициализация нового лог-батча к примеру) или по выходу юзера из Нава.
 


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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 13:04.