![]() |
|
Модераторы: Akella |
![]()
|
|
| former |
|
|||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 1 Всего: 17 |
Master-detail.
В триггере BeforeInsert master-таблицы выполняется проверка данных и, в случае ошибки, вызывается исключение. Изначально генерацию первичного ключа выполнял в триггере после всех проверок, однако потребовалось получать id добавленной записи для detale-таблицы и обновлять только измененную запись. Стал использовать AutoUpdateOptions компонента FIBDataSet master-таблицы. Но в этом случае генератор изменяется до проверки исключений в триггере. Получается, что если несколько раз возникало исключение, то номер записи будет больше на число исключений. Как избежать многократного изменения значения генератора, но при этом сохранить возможность получения ключа для detail-таблицы и обновления добавленной записи? Active - false/true не предлагать. -------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
|||
|
||||
| aryab |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 2 Регистрация: 21.7.2009 Репутация: 1 Всего: 1 |
Для FireBird 2.0 и больше
после Post поле id добавленной записи будет заполнено значением заполненным в базе |
|||
|
||||
| Deniz |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1251 Регистрация: 16.10.2004 Где: Новый Уренгой Репутация: 22 Всего: 44 |
former, вопрос еще актуален?
-------------------- "Для того чтобы сделать шаг вперед, достаточно пинка сзади" (с) |
|||
|
||||
| former |
|
|||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 1 Всего: 17 |
Deniz, если есть еще вариатны, с удовольствием их выслушаю.
-------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
|||
|
||||
| Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 20 Всего: 329 |
former, я вообще не понимаю, зачем так делать, что вызов исключения влияет на срабатывание генератора?
Ты хоть бы код показал |
|||
|
||||
| former |
|
|||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 1 Всего: 17 |
Именно. В AutoUpdateOptions есть свойство WhenGetGenID, которое имеет wgNever (не используется), wgBeforePost (перед вызовом Post), wgOnNewRecord (при вызове Insert). У меня контроль данных осуществляется в триггерах с вызовом исключений. Получается следующее: wgOnNewRecord Вызываем Insert, генерируется значение ключа, вводим данные, вызываем Post, получаем исключение, а генератор уже изменен. wgBeforePost Вызываем Insert, вводим данные, вызываем Post (генерируется значение ключа), получаем исключение, а генератор уже изменен. А для выполнения Refresh необходимо значение ключа добавленной записи. ИХМО:А код тут не причем. -------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
|||
|
||||
| Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 20 Всего: 329 |
у компоненты базы данных (FibDataBase) есть метод получения кода генератора, его и используй. В этом случае триггер не будешь трогать.
Добавлено через 2 минуты и 33 секунды Пример
Добавлено через 4 минуты и 15 секунд а ты поставь код получения значения генератора после кода вызова исключения тогда в случае исключения код получения значения генератора не будет срабатывать |
|||
|
||||
| former |
|
||||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 1 Всего: 17 |
В твоем коде, в случае возникновения исключения и повторного вызова метода Post, будет сгенерировано новое значение генератора. А если возникнет несколько исключений, то вместо 15-го мы запишем запись с ключем номер 25. Не очень хочется "транжирить" генератор. Именно так я и делаю:
Akella, для Refresh тогда откуда возьмется ключ записи? Это сообщение отредактировал(а) former - 8.9.2009, 10:51 -------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
||||
|
|||||
| Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 20 Всего: 329 |
||||
|
||||
| former |
|
|||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 1 Всего: 17 |
А вот причем:
Обрати внимание на последнюю строку. -------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
|||
|
||||
| Akella |
|
|||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 20 Всего: 329 |
Refresh выполняется после чего? После Update!
абчём говорит эта строка?
Добавлено через 1 минуту и 1 секунду Если речь идёт об insert, то нужн что делать? Правильно - pFibDataSet1.CloseOpen(); |
|||
|
||||
| Deniz |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1251 Регистрация: 16.10.2004 Где: Новый Уренгой Репутация: 22 Всего: 44 |
Вот с этого все и начинается
Попробуй посчитать сколько примерно сотен лет нужно чтобы занять весь генератор при условии что 1 запись вставляется каждую секунду в режиме 24х7. Далее, не совсем понятно почему часть бизнес логики (по обработке 1 записи) вынесена в триггер, а часть остается на клиенте. Далее, такие проверки как в триггере, можно оформить как not null на поле, а на клиенте преобразовывать пустые в null (есть вроде такая опция в FIBPlus) Далее, удивил код с
И наконец, если мне не изменяет память, то после исключения на POST, DataSet остается в режиме редактирования, и повторно onNewRecord не вызывается, если только ты сам не делаешь Cancel. -------------------- "Для того чтобы сделать шаг вперед, достаточно пинка сзади" (с) |
|||
|
||||
| former |
|
||||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 1 Всего: 17 |
Порядка 30 млн. записей в год. В некоторых случаях мне нужна четкая последовательность нумерации. Где такое написано, что преобразование идет на клиенте? Клиент только передает данные.
Это если уникальность в одном поле. А когда уникальность по нескольким полям то как? Какие грабли? Да, именно если пользователь делает Cancel. Это сообщение отредактировал(а) former - 8.9.2009, 14:04 -------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
||||
|
|||||
| former |
|
||||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 1 Всего: 17 |
В опциях стоит RefreshAfterPost:=true. Если установлено свойство WhenGetGenID в wgBeforePost или wgOnNewRecord, Id для обновления берется из него. А если wgNever, то можно подсунуть Refresh-у номер записи и он ее обновит.
Если делать pFibDataSet1.CloseOpen(), то потом нужно будет искать добавленную запись. А так, сразу попадаем на нужную запись. Тем более весь набор данных заново открывать. Это сообщение отредактировал(а) former - 8.9.2009, 14:22 -------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
||||
|
|||||
| Deniz |
|
||||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1251 Регистрация: 16.10.2004 Где: Новый Уренгой Репутация: 22 Всего: 44 |
это твой реальный прирост?
зачем? Поподробнее можно? Обычно id кроме разработчиков никто не видит.
Запрос
Если уж так необходимо гарантировано соблюсти последовательность, то оформить insert into в хранимку с предварительной проверкой и последующей вставкой. Результат храминки или ID или код ошибки (например отрицательный). -------------------- "Для того чтобы сделать шаг вперед, достаточно пинка сзади" (с) |
||||||
|
|||||||
| Akella |
|
||||||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 20 Всего: 329 |
нельзя так с генераторами индексы, индексы... Ты хочешь сказать, что после добавления, если выполнить refresh, то в наборе данных ты увидишь запись? Хм...
И не должен видеть, можно показывать в редких случаях. Ты этот код понимаешь? Для чего он?
Почитай про OLD_, NEW_ и MAS_ в докементации к фибам. И ты вообще знаешь для чего рефреш? Ты не увидишь новой записи в НД, пока не переоткроешь его. Добавлено через 1 минуту и 11 секунд
Опять же, посмотри, что за параметр можно вставить в скобки CloseOpen() |
||||||
|
|||||||
| former |
|
|||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 1 Всего: 17 |
Согласен. А как же область видимости транзакции? При возникновении исключения у меня выполняется Cancel в соответствующих событиях DataSet. Кроме того, открываем Хелен Борри (2-е издание) на стр. 700 и читаем, читаем... Почему? Ведь если в качестве ключа использовать другие уникальные данные, показывать их можно, так почему номер нельзя? Я же объяснил, что требуется четкая последовательность регистрационных карт. Есть определенная процедура (в смысле регламент) исключения и удаления регистрационной карты.
Если использовать генерацию в AutoUpdate Oprions или этот вариант, то после добавления/обновления записи (если установлено в Options RefreshAfterPost->true или принудительно обновлять в соответсвующем событии DataSet) запись появится в наборе данных и гриде и окажется в фокусе. Проверено. Читал. Еще раз повторю, что увижу. Это сообщение отредактировал(а) former - 9.9.2009, 21:59 -------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
|||
|
||||
| Deniz |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1251 Регистрация: 16.10.2004 Где: Новый Уренгой Репутация: 22 Всего: 44 |
Так я про это и говорю. Пример: Условие 1 все транзакции read commited Условие 2 триггер на проверку наличия типа
1. Старт транзакции 1 2. Старт транзакции 2 3. Транз№1 Insert into table (id) values (1); 4. Транз№2 Insert into table (id) values (1); 5. Транз№1 Commit 6. Транз№2 Commit Как думаешь сколько записей с id=1 будет в БД? И вызовется ли исключение? -------------------- "Для того чтобы сделать шаг вперед, достаточно пинка сзади" (с) |
|||
|
||||
| Akella |
|
||||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 20 Всего: 329 |
Потому что пользователи ныть начинают... типа: "А я хочу по порядку...." и т.д. и т.п. А тут уже даже программист хочет по порядку
Стормозил, ты не увидишь данных, которые были добавлены другими транзакциями. |
||||
|
|||||
| former |
|
||||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 1 Всего: 17 |
Сегодня проведу эксперимент.
Два поста подряд пытаюсь донести суть. Строгая нумерация не моя прихоть. Яркий пример бухгалтерия, где номера договоров, счетов, инвентарных номеров и прочих документов идет в строгой последовательности. Что прикажешь делать? Как им присваивать номера?
Для этого используется отдельная кнопка, которая переоткрывает DataSet, т.е. делает полный Refresh. А то получится, что пользователь добавил запись и должен заново выполнять поиск, фильтрацию и т.д., что бы продолжить с ней работать. Согласись, что нажать на одну кнопку он всегда успеет, чем искать каждый раз нужную запись. Кроме того, каждый раз ворочить большин набором данных не очень-то экономично, по отношению к ресурсам и нагрузки на сеть и сервер, особенно, если пользователей много. -------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
||||
|
|||||
| Deniz |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1251 Регистрация: 16.10.2004 Где: Новый Уренгой Репутация: 22 Всего: 44 |
Не надо путать искусственный ключ с номером договора. А если с нового года/пятилетки/и т.д. нужно начать нумерацию с начала? Что будешь делать? Обычно делают так: 1. ID никто, кроме программиста, не видит. 2. Под № договора выделяют отдельное поле или несколько полей. 3. Строится уникальный индекс по полям "№ договора" + Год, может еще какие поля можно добавить. 4. ID получают в начале редактирования. 5. К этому ID привязывают detail таблицы. 6. Итоговый номер договора генерируется после того, как сделаны все проверки и данные договора добавлены. -------------------- "Для того чтобы сделать шаг вперед, достаточно пинка сзади" (с) |
|||
|
||||
| former |
|
|||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 1 Всего: 17 |
Deniz, индексы это хорошо, а вот что тогда с исключениями делать? Какого формата сообщение увидит пользователь в результате исключения?
Т.е. для номера договора должен использоваться отдельный генератор? Это сообщение отредактировал(а) former - 10.9.2009, 14:56 -------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
|||
|
||||
| Akella |
|
||||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 20 Всего: 329 |
Так создай им отдельное поле № договора!!! Добавлено через 35 секунд А если прийдётся изменить значение? Ты дашь пользователю редактировать значение поля первичного ключа? Ну ну Добавлено через 1 минуту и 28 секунд Создай ещё один генератор для номера договора и/или сам на клиенте атоматом подставляй. Добавлено через 10 минут и 55 секунд ааа, Deniz уже написал Добавлено через 12 минут и 21 секунду
да!!! Можно делать и
|
||||
|
|||||
| former |
|
||||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 1 Всего: 17 |
Deniz, с транзакция ми действительно прав. Но как тогда быть с сообщениями исключений, если использовать индексы? Ведь они должны быть понятны пользователю.
Нет, пользователь ничего не редактирует. Номер карты присваивается генератором.
Ну это только при условии, что номер состоит из одних цифр. Akella, так что с Refresh-ом? Это сообщение отредактировал(а) former - 10.9.2009, 18:37 -------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
||||
|
|||||
| former |
|
|||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 1 Всего: 17 |
Deniz, Akella, спасибо за помощь!
С исключениями я разобрался, используя репозиторий. А вот с номером договора так и не понятно, в какой момент его нужно генерировать и где? -------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
|||
|
||||
| Akella |
|
||||||
![]() Творец ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 18485 Регистрация: 14.5.2003 Где: Корусант Репутация: 20 Всего: 329 |
Но всё равно когда-нибудь понадобится изменять номер карты, корректировать, мало ли. Если будет отдельное поле - без проблем, а если ковырять первичный ключ....
а так?
При условии, что поле LCD типа Timestamp Это сообщение отредактировал(а) Akella - 10.9.2009, 19:09 |
||||||
|
|||||||
| former |
|
|||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 1 Всего: 17 |
-------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
|||
|
||||
| Deniz |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1251 Регистрация: 16.10.2004 Где: Новый Уренгой Репутация: 22 Всего: 44 |
вот и славненько
Как выглядит этот номер? Как он должен генерироваться? Кто отвечает за генерацию? По своему опыту могу сказать, что в таких номерах (договор, вх. документ и т.д.) обычно присутствуют разные буквы и метасимволы, причем автоматизировать процесс генерации бывает достаточно сложно. Иногда лучше назначить одного ответственного, кто будет вбивать № договора во внесенный в БД документ, чем попытаться определить след. номер от "458-П/2009/В-32". -------------------- "Для того чтобы сделать шаг вперед, достаточно пинка сзади" (с) |
|||
|
||||
| former |
|
|||
![]() MEMS Expert ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1166 Регистрация: 1.3.2006 Где: Россия Репутация: 1 Всего: 17 |
Ручной ввод - самое простое, что можно придумать. Но человеческий фактор.... Я уже кое-что сам вчера придумал. Можно использовать префиксы для каждого типа договора. Создать для них отдельную таблицу. Например, для 458-П/2009/В-32: Префикс - -П/2009/В- (для каждого типа договора свой) Изменяемые части - 458 и 32. Для них генераторы. Значения получать в процессе редактирования, в зависимости от условий договора. Что-то вроде регулярных выражений. Безусловно, такой подход имеет свои недостатки. Это сообщение отредактировал(а) former - 11.9.2009, 09:06 -------------------- Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами. |
|||
|
||||
| Deniz |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1251 Регистрация: 16.10.2004 Где: Новый Уренгой Репутация: 22 Всего: 44 |
former, не все так просто, все зависит от того, какой на Вашем предприятии принят алгоритм формирования номеров.
Поскольку официально-декларирующего алгоритма нет, то каждый извращается как хочет, например (458-П/2009/В-32): 458 - порядковый номер П - тип договора 2009 - год заключения В-32 - дополнительные параметры по договору Может быть два одинаковых порядковых номера но с разными типами 458-П и 458-С.
В общем удачи. -------------------- "Для того чтобы сделать шаг вперед, достаточно пинка сзади" (с) |
|||
|
||||
![]()
|
| Правила форума "Interbase" | |
|
|
Обязательно указание: 1. Версию InterBase (Firebird, Yaffil) 2. Способа доступа (ADO, BDE, IBX и т.д.)
Если Вам понравилась атмосфера форума, заходите к нам чаще! С Уважением, Akella. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Firebird, Interbase | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |