|
|
Регистрация Восстановить пароль |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
|
Опции темы | Поиск в этой теме |
29.09.2008, 05:37 | #1 |
Форумчанин
Регистрация: 04.10.2007
Сообщений: 106
|
"not null" и триггер в IBase/FB
Всем доброе время суток.
В ходе работы с СУБД InterBase/FireBird столкнулся со следующей структурой таблицы: Поле-идентификатор(ключ) таблицы - integer и not null, все отлично это гарантирует наличие значения для каждой записи, но не уникальность значений. Для ключевого поля также есть триггер(ну и генератор), гарантирующие - наличие значения + его уникальность! Такая структура видимо правильна но мне не удобна поскольку не позволяет сделать AppendRecord. Очень хочется убрать not null, т.к. триггер(+генератор) важнее. В связи с этим вопрос: Считаю что для ключевого поля можно не ставить ограничение not null если для этого поля уже есть триггер на BeforeInsert. Ведь сам факт обработки события "перед вставкой" записи гарантирует что значение в поле будет, + генератор дает автоинкремент т.е. уникальность. Правильно ли я рассуждаю? Каквы мнения участников форму на данный счет?
Все не так плохо, как вам кажется, на самом деле все гораздо хуже.
http://delphiworld.narod.ru/dw.html - 5000 статей!!! удобный поиск, оффлайн сборник, рекомендую всем |
29.09.2008, 15:06 | #2 |
Форумчанин
Регистрация: 20.06.2007
Сообщений: 270
|
А если кто-то впоследствии удалит это значение во время редактирования?
-Кукушка, кукушка! Накукуй мне сто лет!
-А накукуй тебе столько? (с) Библия. Вольный перевод с древнееврейского. |
29.09.2008, 16:09 | #3 |
Форумчанин
Регистрация: 28.07.2007
Сообщений: 361
|
Для ключевого поля без not null неполучится. Правило Not null для ключевых полей зашито в систему и требуется обязательно.
А что за проблема с AppendRecord??? Последний раз редактировалось Rik; 29.09.2008 в 16:11. |
01.10.2008, 05:32 | #4 | |
Форумчанин
Регистрация: 04.10.2007
Сообщений: 106
|
А кто ж даст пользователю такую возможность? Даже если значение поля будет отображаться то оно будет нередактируемым.
Цитата:
При попытке вызвать процедуры вставки или добавления (Insert/Append) новой пустой записи появляется сообщение о том что это поле должно иметь значение, но если при вставке явно задаю значение также появляется ошибка. Да и мое мнение и мнение генератора по этому значению могут разойтись . И генератор дает значение до меня - триггер же висит на событие BeforeInsert. И тогда добавление возможно только по SQL запросу INSERT. Такой запрос меня напрягает - полей в таблице много, нужно много писанины и выше вероятность ошибки. Но вот если не ставить not null то все нормально - добавляются записи, и я могу проходить все поля по их индексам и присваивать значения в цикле. Такой путь оказался очень удобным при копировании записей из .mdb таблицы в IB с одинаковыми полями.
Все не так плохо, как вам кажется, на самом деле все гораздо хуже.
http://delphiworld.narod.ru/dw.html - 5000 статей!!! удобный поиск, оффлайн сборник, рекомендую всем |
|
01.10.2008, 06:26 | #5 | |
Форумчанин
Регистрация: 20.06.2007
Сообщений: 270
|
Цитата:
Сама БД и интерфейс работы с ней, IMHO, разные вещи. Поэтому, если есть возможность обеспечить целостность БД средствами сервера БД, я предпочитаю по максимуму использовать их.
-Кукушка, кукушка! Накукуй мне сто лет!
-А накукуй тебе столько? (с) Библия. Вольный перевод с древнееврейского. Последний раз редактировалось Andrei; 01.10.2008 в 11:52. |
|
02.10.2008, 23:27 | #6 | |||
Форумчанин
Регистрация: 28.07.2007
Сообщений: 361
|
Цитата:
Цитата:
Цитата:
Последний раз редактировалось Rik; 02.10.2008 в 23:37. |
|||
03.10.2008, 05:44 | #7 | |||||||
Форумчанин
Регистрация: 04.10.2007
Сообщений: 106
|
Цитата:
Цитата:
Цитата:
Значение из генератора берет за меня сервер БД при выполнении компонентом IBTable процедуры Append, затем я заполняю остальные поля. Вот на это я и надеюсь. Примерно так: ... IBTable.Append: IBTable.FieldByName[FIELDNAME].Value:=XXX; for i:=y to z do begin IBTable.Fields.Field[i].Value:=ADOTable.Fields.Field[(i+a)].Value; end; ... Смысл в том что я обхожу циклом все 30-40 полей и обращаюсь по их индексу. При этом происходит импорт из адошной таблицы с похожей структурой. Т.Е. 10-20 полей подряд одинаковые и я их значения забираю не используя обращение по имени, только по индексу поля. Цитата:
А вот такой перебор дает эту возможность если я знаю что есть несколько одинаковых полей у двух наборов данных . На это я и рассчитываю, но тогда считаю not null избыточностью. Цитата:
Цитата:
Цитата:
Все не так плохо, как вам кажется, на самом деле все гораздо хуже.
http://delphiworld.narod.ru/dw.html - 5000 статей!!! удобный поиск, оффлайн сборник, рекомендую всем |
|||||||
03.10.2008, 07:55 | #8 | |
Форумчанин
Регистрация: 28.07.2007
Сообщений: 361
|
Цитата:
Другой момент, возникнет ситуация, когда вы не сможете подставить идентификатор по такому способу. Если нет идентификатора записи, как сервер узнает, в какую запись нужно подставить этот самый идентификатор? Рано или поздно возникнет момент, когда вы попытаетесь пронумеровать одну запись, а уникальный идентификатор, пропишется сразу в несколько записей и уникальным уже не будет, скорее всего, эта беда уже с вами случилась, а без not null и уникального индекса вы её и не заметили. Затем, при попытке отредактировать или удалить такую запись, у вас одновременно отредактируются или удалятся не одна, а все записи у которых совпал идентификатор. На счет генератора. Представте, два пользователя одновременно добавляют запись, не используя генератор. Они выяснили, что последняя запись была 1000, и они оба свои записи пронумеровали как 1001 и в результате в базу добавилось две записи с номером 1001, не имея уникального индекса на ключевое поле, сервер это всё пропустит. Генератор же обеспечит уникальность, сколько бы пользователей к нему не обращалось одновременно. На всех нормальных SQL серверах нет автоинкрементных полей, для этого существуют последовательности, в IB/FB они называются генераторы, счас их тоже переименовали в последовательности... |
|
03.10.2008, 08:51 | #9 |
Форумчанин
Регистрация: 28.07.2007
Сообщений: 361
|
Surgeon
Видимо я вас неправильно понял, но совершенно ясно одно, с ключевыми полями лучше не эксперементировать, это все придумано не вчера и всё проверено временем. На ключевое поля не только not null надо но и primary key. Последний раз редактировалось Rik; 03.10.2008 в 08:56. |
04.10.2008, 06:05 | #10 | ||||
Форумчанин
Регистрация: 04.10.2007
Сообщений: 106
|
Цитата:
Цитата:
Цитата:
Цитата:
======== Еще раз: я предлагаю сравнить следующие ситуации и цепочки событий: 1.Есть триггер на BeforeInsert+ генератор. Когда я вызываю IBTable.Append на сервер БД уходит команда на вставку записи. Сервер обрабатывает событие BeforeInsert, т.е. еще до реального добавления записи запрашивает значение генератора и заносит в соответствующее поле записи. Т.е. уже обеспечивает уникальность идентификатора. Затем я заполняю остальные поля данной записи. Затем уже IBTable.Post и после добавления нужного числа записей IBTransaction.CommitRetaining. 2.Есть триггер на BeforeInsert+ генератор, и поле-идентифкатор объявлено как not null. Когда я вызываю IBTable.Append на сервер БД уходит команда на вставку записи. Вот тут вылетает ошибка что поле не может быть null. Отсюда я делаю вывод что проверка на not null сервером БД осуществляется раньше чем присваевается значение из генератора! Если же я буду выполнять IBTable.AppendRecord(IDValue,Field1 Value...FieldNValue), т.е в процедуре сразу присваивать значения полям записи включая поле-идентификатор, то значение поля-идентификатора будет конфликтовать со значением взятым из генератора. 3.Есть триггер на BeforeInsert+ генератор, и поле-идентифкатор объявлено как not null. Вызывается выполнение запроса с текстом типа : 'insert into mytable ....' Вот что происходит дальше в этом варианте я не совсем понимаю потому что ошибок не генерируется, значит значение из генератора закидывается до проверки на not null? ==== Так вот в связи с этими варантами я интересуюсь : - почему не прокатывает 2, - как срабатывает 3-ий - чем плох 1-ый (мне нравится) Т.е при любом раскладе используется триггер+генератор, так что меня за их использование не надо агитировать, я и так "за!".
Все не так плохо, как вам кажется, на самом деле все гораздо хуже.
http://delphiworld.narod.ru/dw.html - 5000 статей!!! удобный поиск, оффлайн сборник, рекомендую всем |
||||
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Ошибка при использовании OlePropertyGet("Documents").OleProcedure("Add") в C++ Builder | AleksP | C++ Builder | 7 | 11.04.2009 13:06 |
если пользователь наберет какой-то другой символ не "y" или "n" и нажмет enter, программа проигнорирует | skobets | Общие вопросы C/C++ | 2 | 03.06.2008 06:51 |
Excel файл открывается не "до конца" (странички "не показываются" только серое поле) | Dorvir | Microsoft Office Excel | 2 | 28.03.2008 10:03 |
Создаю диаграмму "Bar". Подскажите как убрать растояние между "столбами" | MAcK | Компоненты Delphi | 11 | 24.10.2007 10:49 |
На чем пишутся стратегии типа "Казаков" и "Эпохи империи" | Tayfun | Свободное общение | 3 | 26.06.2007 20:27 |