|
07.08.2008, 18:15 | #1 |
Участник
|
Итак, как мы все знаем в таблицах Navision для поля типа Integer есть замечательно поле AutoIncrement. Всем понятно, зачем оно нужно. Здесь уже много шло дискуссий на эту тему.
Опишу ситуацию из которой следует, что использование оного свойства может создать кучу проблем (рассматриваем NAV+SQL). Итак.. Есть таблица, в которой есть поле "No." с AutoIncrement = ДА. Вставлять из интерфейса в такую таблицу труда не составляет и ошибок не дает. Поле само увеличивается и, вроде, все хорошо. Проблемы возникают, если вставлять в такую таблицу кодом. Нужно всегда помнить о том, что именно в этой таблице именно это поле инкрементное и, следовательно, его не нужно указывать или вычислять. Это не всегда возможно, например по той причине, что кадры могут меняться и новому человеку неизвестно о таких нюансах, как автоинкрементное поле в какой-то там таблице. Допустим ситуацию - в таблицу вставляются 100 записей. Далее, в процессе работы (по каким-то причинам), последние 5 записей удаляются. Знающие люди понимают, что при вставке новой записи в эту таблицу через интерфейс новая запись будет иметь поле "No." равное 101, а не 96, как того хотелось бы. Т.е. "дыры" в нумерации остаются. Но это не главное. Допустим теперь, что новый человек получил некую постановку с использованием это таблицы. Ничего не подозревая об автоинкременте, он получает последнее значение (как, например, получается последнее значение 17 таблицы при учете). Это значение в рассматриваемом примере равно как раз 96. Далее, пишется код вставки, а в результате выполнения кода вылезает ошибка SQL-сервера. Для понимания источника ошибки рассмотрим техническую сторону вопроса: 1. При удалении строк из таблиц с автоинкрементным полем значение этого инкремента не меняется. В нашем случае оно осталось равным 101. 2. SQL сервер позволяет осуществлять принудительную вставку своего значения в инкрементные поля. Для этой цели используется спец. команда (SET IDENTITY_INSERT если быть точным). 3. Принимая во внимание пункты выше - в нашем случае поисходит следующее: при принудительном указании поля "No." Navision выполняет указанную в п.2 команду и осуществляется вставка в обход автоинкремента поля. А где же ошибка, спросите вы? А суть в том, что для выполнения указанной в п.2 команды пользователь должен обладать минимум ролью db_owner на сервере, что для обычного пользователя системы, обычно, не есть так. Именно с этим фактом ошибка и связана. Таким образом, получается, что если уж вы используете оное свойство поля, то должны везде его документировать как важный пункт разработки, чтобы люди, которые будут писать код после вас не попались на эту неприятную ошибку. Или не использовать автоинкремент в принципе. Кстати, как вы думаете, почему, например в 17 таблице, поле "Entry No." не инкрементное, казалось бы - самое применение...
__________________
"И лишь патологоанатом не берет работу на дом" (с) Вишневский |
|
07.08.2008, 19:40 | #2 |
Участник
|
Забавный пост ))
Вообще много о чем нужно помнить, если разработкой занимаются несколько человек. А то и новенькие. Но это не значит, что от каких-либо вещей стоит отказываться. Автоинкрементным делают почти всегда поле, которое надо чтобы было. Просто чтобы там сама собой вставала ничего не значащая цифра. Вопросы "дыр" и "последних значений" вообще не должны никого интересовать по-хорошему. А если интересуют - значит выбран не подходящий вариант реализации. Вот так я тумаю. пс. Единственное, при записи в таблицу автоинкрементному полю надо явно присвоить 0. И фсе, что нужно для щястья. |
|
08.08.2008, 01:19 | #3 |
Участник
|
Цитата:
Сообщение от romeo
Забавный пост ))
Вообще много о чем нужно помнить, если разработкой занимаются несколько человек. А то и новенькие. Но это не значит, что от каких-либо вещей стоит отказываться. Автоинкрементным делают почти всегда поле, которое надо чтобы было. Просто чтобы там сама собой вставала ничего не значащая цифра. Вопросы "дыр" и "последних значений" вообще не должны никого интересовать по-хорошему. А если интересуют - значит выбран не подходящий вариант реализации. Вот так я тумаю. пс. Единственное, при записи в таблицу автоинкрементному полю надо явно присвоить 0. И фсе, что нужно для щястья. Да и, видимо, Вы плохо читали пост.. Речь идет о баге SQL сервера из за которого работа с инкрементными полями из Навика может проблемно проходить.. Если Вы это знаете - Вы молодец, я за Вас рад. А если не знаете - так узнайте.. И обретете... А если из всего поста Вы поняли только про "дыры" в нумерации - читайте матчасть дальше. Ничего личного, как говорится...
__________________
"И лишь патологоанатом не берет работу на дом" (с) Вишневский |
|
08.08.2008, 01:31 | #4 |
Участник
|
Цитата:
Вообще много о чем нужно помнить, если разработкой занимаются несколько человек.
Цитата:
Но это не значит, что от каких-либо вещей стоит отказываться.
Цитата:
Автоинкрементным делают почти всегда поле, которое надо чтобы было.
Цитата:
Вопросы "дыр" и "последних значений" вообще не должны никого интересовать по-хорошему. А если интересуют - значит выбран не подходящий вариант реализации.
Цитата:
Вот так я тумаю.
Цитата:
пс. Единственное, при записи в таблицу автоинкрементному полю надо явно присвоить 0. И фсе, что нужно для щястья.
__________________
"И лишь патологоанатом не берет работу на дом" (с) Вишневский |
|
08.08.2008, 10:19 | #5 |
Участник
|
Цитата:
"Или не использовать автоинкремент в принципе." - это ваши слова. Надеюсь хоть их я истолковал верно. Цитата:
Цитата:
Мне все равно каким буквосочетанием принято обозначать свое мнение. Все, что я говорю - мое мнение. |
|
08.08.2008, 10:35 | #6 |
Участник
|
Цитата:
...
Ошибка вызвана попыткой принудительного присвоения значения пользователем в поле. Принудительным из-за попытки устранить "дыры" в нумерации. Давайте не передергивать. Я вижу вы хороший спорщик, только спорьте аргументированно. Я предложил способ, устраняющий проблемы вставки - принудительно присваивайте лишь одно значение перед инсертом - Ноль. ... Да, я согласен с Вами, что необходимо изучать структуру таблицы перед разработкой.. И считаю это первостепенной задачей. Но в этом "забавном" посте я всего лишь показал, что может произойти, если человек этого не сделает.. Насчет использования инкремента в принципе - да, я против, так как считаю инкремент граблями другого разработчика, поставленными для него автором таблицы только из за того, что ему (автору) было Далее, в Вашем опусе на мой "забавный пост" Вы сказали, что инкрементное поле, дескать, это никому не нужное число. Позвольте с Вами не согласиться.. С каких пор ПК (а ведь изначально, в SQL, такие поля именно для ПК используются) стал никчемным и ненужным полем?
__________________
"И лишь патологоанатом не берет работу на дом" (с) Вишневский |
|
08.08.2008, 10:41 | #7 |
Участник
|
Цитата:
пс. Задело, я вижу, вас слово "забавный" )))) Забавно. Ну лексикон у меня такой. ппс. А сейчас, ВНИМАНИЕ, я выдаю желаемую вами ОСь на пост - уважаемый FoxSoft2005, спасибо за столь нужное замечание по работе с автоинкрементными полями в Навижен. |
|
08.08.2008, 12:03 | #8 |
Участник
|
Цитата:
Код: GLEntry.LOCKTABLE; IF GLEntry.FIND('+') THEN BEGIN NextEntryNo := GLEntry."Entry No." + 1; |
|
08.08.2008, 09:21 | #9 |
Участник
|
FoxSoft2005 - Вы все правильно написали. Нужно только помнить о том что автоинкремент работает только в SQL версии Nav - видимо потому стандартный функционал его не использует.
К вопросу включать автоикремент или нет следует подходить очень осторожно, например автоинкремент в книгах операций на мой взгляд дело бессмысленное и опасное. Код: Locktable; Find('+'); при учете используется в том числе для блокировки последней записи таблицы, пока первый пользователь учет не закончил - все остальные ждут получения последнего номера операции. Допускаю, что Вас неустраивают блокировки и рассматриваете автоинкремент как средство для решения задачи одновременного учета несколькими пользователи. В этом случае Вам придется сильно переработать учетные кодеюниты, в частности при учете фин. журнала отказаться от формирования операций сначала во временных таблицах, с последующим сбросом в базу. Для решения задачи одновременного учета есть другие механизмы - например разделение номеров операций по диапазонам. romeo +1. |
|
08.08.2008, 10:12 | #10 |
Участник
|
Цитата:
...автоинкремент работает только в SQL версии Nav...
__________________
"И лишь патологоанатом не берет работу на дом" (с) Вишневский |
|
08.08.2008, 10:29 | #11 |
Участник
|
|
|
08.08.2008, 10:34 | #12 |
Участник
|
Цитата:
Кстати, как вы думаете, почему, например в 17 таблице, поле "Entry No." не инкрементное, казалось бы - самое применение...
вот ссылка на презентацию и скрипты по дедлокам и блокировкам. В презентации на 15 странице, чел советует использовать поля "Entry No." с типом автоинкремент для учетных таблиц. А стандартный код - просто он был написан очень давно, и следуя старой доброй традиции - под автоинкремент просто не оптимизировался. Цитата:
Нужно только помнить о том что автоинкремент работает только в SQL версии Nav - видимо потому стандартный функционал его не использует.
Цитата:
2. SQL сервер позволяет осуществлять принудительную вставку своего значения в инкрементные поля. Для этой цели используется спец. команда
... Таким образом, получается, что если уж вы используете оное свойство поля, то должны везде его документировать как важный пункт разработки, чтобы люди, которые будут писать код после вас не попались на эту неприятную ошибку. Или не использовать автоинкремент в принципе. |
|
08.08.2008, 10:49 | #13 |
Участник
|
О, придумал! Давайте откажемся от вычисляемых полей!
Ведь новенький программист не знает, что поле вычислемое, и будет получать там всегда 0! А у FoxSoft2005 плохое настроение, что он так реагирует неадекватно? Критические дни? "читайте матчасть дальше" "Кто Вам сказал такую чушь?" "не все такие супер-пупер одаренные" Ничего личного (с) FoxSoft2005 Нет никакой "баги SQL сервера", строгая и стройная логика. То, что иногда люди не знают, что поле в таблице автоинкрементное - не так страшно, один раз наступив на это, запомнят и будут знать, никаких проблем. |
|
08.08.2008, 10:58 | #14 |
Участник
|
Да что Вы? Уверены? Точно точно уверены?
http://support.microsoft.com/kb/302621 А ведь именно этото код ошибки выдается... P.S. Конечно понятно, что слово BUG и Майкрософта уже ассоциируется с FEATURE.. Но все же! P.S.S. Правда речь там идет о не о конкретно инкременте - но о более общей команде SET.
__________________
"И лишь патологоанатом не берет работу на дом" (с) Вишневский |
|
08.08.2008, 11:04 | #15 |
Участник
|
Цитата:
Сообщение от SVG
О, придумал! Давайте откажемся от вычисляемых полей!
Ведь новенький программист не знает, что поле вычислемое, и будет получать там всегда 0! А у FoxSoft2005 плохое настроение, что он так реагирует неадекватно? Критические дни? "читайте матчасть дальше" "Кто Вам сказал такую чушь?" "не все такие супер-пупер одаренные" Ничего личного (с) FoxSoft2005 Нет никакой "баги SQL сервера", строгая и стройная логика. То, что иногда люди не знают, что поле в таблице автоинкрементное - не так страшно, один раз наступив на это, запомнят и будут знать, никаких проблем. Правда вот передергивать не стоит ... P.S. Я вот поражаюсь... Уважаемый, Вы, например, всегда были классным разработчиком (уверен, что это так!!) навижн? Прямо родились таковым? Или этот форум только для ассов?
__________________
"И лишь патологоанатом не берет работу на дом" (с) Вишневский |
|
08.08.2008, 11:15 | #16 |
Участник
|
В своем посте вы предлагаете отказаться от одной из возможностей навижен, которая знающим людям кажется вполне удобной и нужной. Зачем это новичку? Надеюсь люди вполне адекватны, чтобы осторожно следовать советам на форуме. Как здесь уже сказали, есть еще одно "замечательное" свойство AutoSplitKey. Пользователю вообще не понятно, почему происходит ошибка, если он поменял порядок записей в субформе и хочет вставить еще одну запись. Много есть неприятностей в нави. Но это нави. И это главный нюанс нашей работы.
|
|
08.08.2008, 11:00 | #17 |
Участник
|
"Насчет использования инкремента в принципе - да, я против, так как считаю инкремент граблями другого разработчика"
Т.е. вопреки всем рекоммендациям вы настаиваете на архаичном поиске последнего значения? )))) Это во-первых медленно, во-вторых ведет к блокировкам, в-третьих требует нескольких ненужных минут программирования. И для чего? Если вам так мешают автоинкременты, используйте CLEAR(Record) вместо Record.INIT и вы навсегда забудете об этой проблеме!!! |
|
08.08.2008, 11:11 | #18 |
Участник
|
Цитата:
Сообщение от SVG
"Насчет использования инкремента в принципе - да, я против, так как считаю инкремент граблями другого разработчика"
Т.е. вопреки всем рекоммендациям вы настаиваете на архаичном поиске последнего значения? )))) Это во-первых медленно, во-вторых ведет к блокировкам, в-третьих требует нескольких ненужных минут программирования. И для чего? Если вам так мешают автоинкременты, используйте CLEAR(Record) вместо Record.INIT и вы навсегда забудете об этой проблеме!!! Выставьте автоинкремент на 17 таблице, перепишите код в 12 кодеюните для одновременного учета.. и готовтесь ловить фантомы. Навижн не позволяет явно управлять ни уровнем блокировки ни уровнем изоляции. PS. Если Вы предложите другой способ гарантирования блокирования последней записи, кроме как Locktable; Find('+') с удовольствием его проанализирую. |
|
08.08.2008, 11:04 | #19 |
Участник
|
"http://support.microsoft.com/kb/302621"
Здесь речь о BULK INSERT, при чем тут вставка единичной записи в таблицу? Этта... Я не только не родился классным программистом, я вам больше скажу ))))) Когда я впервые столкнулся с такой фигней - вставляю запись в таблицу, а оно мне - не могу вставить Я ПРОСТО ЗАМАНАЛСЯ ИСКАТЬ почему эта дрянь ругается, реально ЗАМАНАЛСЯ, убил минут 15 точно А потом увидел автоинкремент Запомнил, и больше инкремент проблем не вызывает ) |
|
08.08.2008, 11:28 | #20 |
Участник
|
BULK_INSERT это одно из проявлений бага. А сам баг связан с невозможностью выполнить SET.
__________________
"И лишь патологоанатом не берет работу на дом" (с) Вишневский |
|