Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» InterBase и FireBird: вопросы по работе и их решение

Автор: ant0ni02004
Дата сообщения: 18.09.2012 02:01
Maximus777
обычно такое для номеров документов требуется. в этом случае просто соотв. документ почечается как удалённый, отменённый итд. если так совсем нельзя - тогда номер объявляется "свободным" (заносится в отд. таблицу хотя-бы) и захватывается след.созданным документом. а перенумеровывать это зря, бардак же будет.
Автор: Maximus777
Дата сообщения: 18.09.2012 05:40
AlexCoRu
Цитата:
мне не нравится, что записи вставленные позже будут иметь меньший id.

Именно это и произойдёт, если ID удалённой строки делать "свободным". А если устроить "перестройку", то всё получится вполне благообразно.

ant0ni02004
Цитата:
а перенумеровывать это зря, бардак же будет

Не осознаю, в чём будет заключаться бардак. Причём я даже могу исключить возможность появления двух одинаковых ID вручную, делая перерасчёт в то время, когда заведомо в базу никто не полезет.
Автор: jonikDk
Дата сообщения: 18.09.2012 08:15

Цитата:
Гугля не помогла, вся надежда на вас.

Это не верный подход, за такое решение бьют по рукам. Хочешь номер для документа, заведи себе еще одно поле в таблице - не PK и правь его себе сколько хочешь, но опять же решение с полной перенумерацией существующих документов - это бред.

Цитата:
Для очистки совести хочется, чтоб один к одному шло.

Для очистки совести не мешало бы почитать теорию СУБД про многопользовательский режим.
Автор: AlexPetrovich
Дата сообщения: 18.09.2012 08:54

Цитата:
Не осознаю, в чём будет заключаться бардак. Причём я даже могу исключить возможность появления двух одинаковых ID вручную, делая перерасчёт в то время, когда заведомо в базу никто не полезет.

Maximus777
Кроме этой базы документы разве нигде не используются ? И даже не печатаются ?
А то сегодня документ с одним номером, завтра с другим - бардак.

Тут уже подсказали - завести отдельную таблицу свободных номеров, заполнить ее изначально например до милииона. Потом при работе помечать номер как занятый. После удаления/освобождения помечать опять как свободный. Очередной номер для нового документа брать процедурой из этой таблицы.

На форуме sql.ru было много холиваров по этой теме, поищи там если интересно.
http://www.sql.ru/forum/actualthread.aspx?bid=2&tid=259311&hl=%e4%fb%f0%ea%e8
http://sql.ru/forum/actualthread.aspx?bid=2&tid=173526&pg=-1&hl=#1444523
Автор: jonikDk
Дата сообщения: 18.09.2012 10:44

Цитата:
Не осознаю, в чём будет заключаться бардак. Причём я даже могу исключить возможность появления двух одинаковых ID вручную, делая перерасчёт в то время, когда заведомо в базу никто не полезет.

Вопрос, какие книги про СУБД вы читали?
Как мне кажется - ни одной.
Автор: miwa
Дата сообщения: 18.09.2012 10:54

Maximus777

Цитата:
AlexCoRu
Цитата:
мне не нравится, что записи вставленные позже будут иметь меньший id.

Именно это и произойдёт, если ID удалённой строки делать "свободным". А если устроить "перестройку", то всё получится вполне благообразно

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

Документ как правило имеет табличную часть (позиции накладной как пример) и хидер (заголовок, шапку, оглавление). В табличной части соответственно делается поле-ссылка на шапку, чтобы разделить, какие позиции к какому документу относятся. Внимание, вопроссы!
А что вы собираетесь делать с табличными частями документов после перенумерации шапок? Также перенумеровывать?
А что делать с трегерами на обновление, которые обязательно появятся (если уже не появились)?
А что делать, когда понадобиться удалить документ месячной давности и это удаление потянет за собой каскадный пересчет всей базы на пару часов в середине рабочего дня?
А что делать, когда ваша программа распечатает документ с номером 234, его выдадут какому-то человеку, потом кто-то удалит документы 123 и 200 с соответствующими изменениями, а потом придет человек с бумажкой на которой написано "234"?

Maximus777

Цитата:
Не осознаю, в чём будет заключаться бардак

Есть два пути чтобы осознать. Первый - делать как хотите, ходить по всех граблях, которые я описал (а их намного больше, очень-очень намного) с соответствующими разгребаниями, разборками с начальством/клиентами и прочими нервотрепками. А второй - потратить пару дней на изучение теории СУБД и особенно многопользовательского режима работы.
Выбор за вами.
Автор: ant0ni02004
Дата сообщения: 18.09.2012 14:38
Maximus777
тяжело помочь т.к. не совсем понятно какая цель этого механизма...
ведь правда не для того, чтобы скрыть сам факт наличия(когда-то) и последующего удаления документа?

Цитата:
Не осознаю, в чём будет заключаться бардак

не хочется повторять то, что уже выше написали, но вкратце
у вас были документы в таблице

Код: ID=1, NUM=1;ID=2, NUM=2;ID=3, NUM=3;ID=4, NUM=4
Автор: Maximus777
Дата сообщения: 18.09.2012 15:37
Уважаемые, вы куда-то в неведомые дали унеслись. Никакого криминала я не замыслил. База используется у меня в офисе для собственных внутренних нужд (а именно, упорядочивание инфы по обзвону потенциальных клиентов). Никакие документы не печатаются. Только раз в месяц выбирается инфа из базы для отчёта (типа отчёт за месяц). ID при этом никак не используется, кроме как для красоты. Т.е. его никто, кроме меня, не видит вообще. О каком бардаке речь?! Откуда такая паранойя?

jonikDk
Цитата:
Вопрос, какие книги про СУБД вы читали?
Как мне кажется - ни одной.

Перед тем, как задать вопрос, проштудировал такую - Borri - Firebird Rukovodstvo razrabotchika baz dannyx [RU].djvu. Хотя Вы правы, опыт мой почти нулевой. И прочтение теории мне не очень помогает, мне бы пример рабочий ...

Ещё раз попробую объяснить суть задачи. В таблице, у каждой строки есть свой ID, присваиваемый по генератору в момент добавления этой самой строки в базу. Например, 1,2,3,4,5,6,7. Значение генератора на этот момент равно 7. Затем удаляется строка с ID = 3. Необходимо, сразу после удаления, 4,5,6,7 превратить в 3,4,5,6 и генератору присвоить значение 6. Строки, имеющие ID ниже, чем у удаляемой никак не трогать. Строк, превышающих ID удаляемой строки, будет крайне мало, поэтому это не должно занять много времени.
Автор: volser
Дата сообщения: 18.09.2012 19:08
Maximus777
На эту таблице нет ссылок foreign key? Зачем вообще это делать? Чем не устраивают иды которые идут не по порядку, если они никуда не выводятся?
Автор: Maximus777
Дата сообщения: 18.09.2012 20:03
volser
Цитата:
На эту таблице нет ссылок foreign key?

Нет.

volser
Цитата:
Зачем вообще это делать?

Если это невозможно сделать или Вы не знаете, как это сделать, то так и скажите. К чему все эти "наводящие" вопросы?
Автор: AlexCoRu
Дата сообщения: 18.09.2012 20:35

Цитата:
Только раз в месяц выбирается инфа из базы для отчёта (типа отчёт за месяц)
А как часто заносится?

Цитата:
ID при этом никак не используется, кроме как для красоты
Тогда зачем он вообще?

Цитата:
Необходимо, сразу после удаления, 4,5,6,7 превратить в 3,4,5,6
Сразу может и не получится, т.к. какая-либо из записей 4,5,6,7 будет блокирована.


Добавлено:
По-моему, генератор не нужен вовсе. Достаточно двух триггеров AfterDelete и BeforeInsert.
Автор: Maximus777
Дата сообщения: 18.09.2012 21:17
AlexCoRu
Цитата:
А как часто заносится?

Каждый день.


Цитата:
Тогда зачем он вообще?

А хз, я уже сам не помню, зачем его задумывал


Цитата:
По-моему, генератор не нужен вовсе. Достаточно двух триггеров AfterDelete и BeforeInsert.

Наверное так, но это мои первые шаги и мне было понятнее с генератором.

Короче, решил проблему с перестройкой ID, через процедуру. Мне не трудно вручную, иногда, наводить красоту. Правда хотелось разобраться с триггерами, с чем их "едят" ...


Код: SET TERM ^ ;
CREATE PROCEDURE REMAKE_ID (
STID integer,
ENID integer )
AS
BEGIN
WHILE (stid<enid) DO
BEGIN
UPDATE CLIENT_CATALOG SET ITEM_ID=:stid-1 WHERE ITEM_ID=:stid;
stid=:stid+1;
END
END^
SET TERM ; ^
Автор: ant0ni02004
Дата сообщения: 18.09.2012 22:45
Maximus777

Цитата:
Никакого криминала я не замыслил

а вам его никто и не шьёт

Цитата:
К чему все эти "наводящие" вопросы?

да вам помочь хотят, только и всего.
ну не может быть такая красота только ради красоты
если вдруг нужно выводить номера в вашем отчете чтобы красиво подряд шли, или количество подсчитывать - так так и скажите, это решается без перестройки ID
ладно, дело ваше в конце концов

Автор: miwa
Дата сообщения: 18.09.2012 22:50
Maximus777

Цитата:
Если это невозможно сделать или Вы не знаете, как это сделать, то так и скажите. К чему все эти "наводящие" вопросы?

На sql.ru в таких случаях принято говорить: «Там обрыв, но вам туда можно». И это очень точно отражает суть. Если вам так сильно хочется пробежаться по краю обрыва, то, безусловно, никто не имеет права вам мешать. Но только не обижайтесь, что помогать никто не рвется.

Касаемо тригеров с генераторами и работы с ФБ вообще - рекомендую еще книгу Вострикова и Ковязина «Мир Interbase». Довольно просто, понятно и доходчиво все расписано.

А ваша процедура REMAKE_ID заменяется одним запросом, кстати:


Код:
update client_catalog set item_id = item_id - 1 where item_id > :param1
Автор: Maximus777
Дата сообщения: 19.09.2012 05:30
ant0ni02004
Цитата:
ну не может быть такая красота только ради красоты

Может.


Цитата:
если вдруг нужно выводить номера в вашем отчете чтобы красиво подряд шли, или количество подсчитывать - так так и скажите, это решается без перестройки ID

В отчёте этих номеров нет.

miwa
Цитата:
Касаемо тригеров с генераторами и работы с ФБ вообще - рекомендую еще книгу Вострикова и Ковязина «Мир Interbase». Довольно просто, понятно и доходчиво все расписано.

Спасибо за совет. Постараюсь изучить данный материал.


Цитата:
А ваша процедура REMAKE_ID заменяется одним запросом, кстати:

Код: update client_catalog set item_id = item_id - 1 where item_id > aram1
Автор: miwa
Дата сообщения: 19.09.2012 09:13
Maximus777

Цитата:
Уверяю Вас, те данные, которые я удаляю, никому не понадобятся в будущем и никакого фатализма не доставят. Это, как правило, неправильно введённые данные (пользователи следом вводят верные). А из интерфейса, который используют пользователи, доступен только ввод информации.

Тут дело даже не в нужности конкретных данных, а в самом принципе, в подходе к работе. Вам сейчас оно неинтерессно и ненужно, но иногда накладные затраты на удаления чего-либо столь велики, что это удаление никогда не делают. Может, помните, был год-два назад скандал с «вконтактом», когда они отказывались удалять пользовательские данные, ссылаясь как раз на техническую невозможность.

Ну или еще пример, тоже не совсем и вашей области, но похоже. Есть шапка документа и табличная часть. В табличной части - отсылки на многие другие таблицы из базы данных - справочник товаров/услуг, валюты там, штрих-коды всякие. Вот, пользователь решает удалить весь документ. А что делать с зависимими таблицами? Удалять ли записи с справочника товаров? А если штрих-коды генерируются по специальному (не бездырочному, но что-то похожее) алгоритму? Ну и куча других подобных нюансов.

Но это все так, мысли в сторону.

Вот, кстати, еще. Если вы предпочитаете практику, посмотрите на ресурс sql-ex.ru - там как раз голая практика. Тренировка по составлению самых разных запросов на любые случаи жизни. Вы наверняка удивитесь, узнав, сколько всего можно сделать обычным запросом (а не только перенумеровать документы)
Автор: jonikDk
Дата сообщения: 19.09.2012 09:52

Цитата:
Перед тем, как задать вопрос, проштудировал такую - Borri - Firebird Rukovodstvo razrabotchika baz dannyx [RU].djvu. Хотя Вы правы, опыт мой почти нулевой. И прочтение теории мне не очень помогает, мне бы пример рабочий ...

Ну вот начало есть это хорошо.
Вот мы все с практической точки зрения и советуем тебе не делать глупостей
А понятие красоты у каждого своё, а вот целесообразность данного действа понимается с опытом работы в многопользовательском режиме. Если ты это не можешь понять, то проще себе сказать, что это табу, так мне сказали умные люди
Потом когда наберешься опыта и поймешь, скажешь спасибо

Добавлено:
Да и еще, подумай над таким вопросом:
Одновременно создали запись 3 клиента
1 получил id - 10
2 получил id -11
3 получил id - 12
Но 1 и 2 затем решили отменить ввод документа или произошла ошибка при вводе (это не важно, важно, что документ не сохранился) у тебя получится ряд id - 9,12 то есть будет дырка в два номера
И я не понимаю, чем тебе поможет твой update в таком случае.
Автор: Maximus777
Дата сообщения: 19.09.2012 11:45
miwa
Цитата:
Ну или еще пример, тоже не совсем и вашей области, но похоже. Есть шапка документа и табличная часть. В табличной части - отсылки на многие другие таблицы из базы данных - справочник товаров/услуг, валюты там, штрих-коды всякие. Вот, пользователь решает удалить весь документ. А что делать с зависимими таблицами? Удалять ли записи с справочника товаров? А если штрих-коды генерируются по специальному (не бездырочному, но что-то похожее) алгоритму? Ну и куча других подобных нюансов.

Это всё совершенно неоспоримо. Но у меня одна база, одна табличка и никаких ссылок. Если в будущем они (ссылки) появятся, то и мои подходы изменятся.

jonikDk
Цитата:
Да и еще, подумай над таким вопросом:
Одновременно создали запись 3 клиента
1 получил id - 10
2 получил id -11
3 получил id - 12

У меня этого нет. 1 - это ID1, 2 - это ID2. Клиент не имеет уникального ID, его имеет каждая строка в табличке. Не спрашивайте зачем так сделано, сам не знаю. Я только учусь. При этом стараюсь совмещать приятное с полезным.
Автор: jonikDk
Дата сообщения: 19.09.2012 12:22

Цитата:
У меня этого нет. 1 - это ID1, 2 - это ID2. Клиент не имеет уникального ID, его имеет каждая строка в табличке. Не спрашивайте зачем так сделано, сам не знаю. Я только учусь. При этом стараюсь совмещать приятное с полезным.


Ну так я это и имел в виду.
Распишу еще раз, есть три пользователя, вводят документы в твою таблицу:
1 пользователь вводит документ, сгенерировался id записи равный 10
2 пользователь вводит документ, сгенерировался id записи равный 11
3 пользователь вводит документ, сгенерировался id записи равный 12

1 и 2 пользователи не сохранили документы, 3 сохранил. Получилась дырка, в твоей таблице id будут иметь значения - 1,2,3,4,5,6,7,8,9,12.
Где в этом случае твоя красота? Или здесь я делаю красиво, а здесь фиг с ним?
Автор: Maximus777
Дата сообщения: 19.09.2012 12:59
jonikDk
Цитата:
1 и 2 пользователи не сохранили документы, 3 сохранил.

В моём случае так не бывает . Если была нажата кнопка "ОК", то данные ушли в базу. А когда они входили в базу, то все сопутствующие причиндалы им были присвоены (ID и т.д.). Пока пользователи вводят инфу, база отдыхает. Если пользователь закрыл форму добавления, то и в базу ничего не ушло. Понимаете? События "сгенерирован ID" и "документ сохранён" происходят в один и тот же момент времени.

"Дырку" могу сделать только я сам, как правило по просьбе пользователей, чтобы удалить некорректную инфу. После этого я "делаю красиво" И делаю я это совсем другим инструментом, если быть точным, то с помощью FlameRobin. Из пользовательского интерфейса (который в моём случае представлен в Excel) удалить данные невозможно.
Автор: jonikDk
Дата сообщения: 19.09.2012 13:25

Цитата:
В моём случае так не бывает . Если была нажата кнопка "ОК", то данные ушли в базу. А когда они входили в базу, то все сопутствующие причиндалы им были присвоены (ID и т.д.). Пока пользователи вводят инфу, база отдыхает. Если пользователь закрыл форму добавления, то и в базу ничего не ушло. Понимаете? События "сгенерирован ID" и "документ сохранён" происходят в один и тот же момент времени.

Ха, в момент когда пользователь нажал кнопку сохранить, сосед прикольнулся и выдернул шнур из ethernet разъема. Произошла любая другая ошибка при сохранении. То что при сохранении не произойдет ошибки, ты не можешь гарантировать.

Цитата:
События "сгенерирован ID" и "документ сохранён" происходят в один и тот же момент времени.

Очень смелое утвеждение
Цитата:

"Дырку" могу сделать только я сам, как правило по просьбе пользователей, чтобы удалить некорректную инфу.

Интересно - "ручной программист". Программы надо писать так, чтобы участие программиста сводилось к минимуму. Либо если есть нужда в запрете каких либо действий, то создается административная тулза(учетка), в которой разрешено удалять данные.
Автор: Maximus777
Дата сообщения: 19.09.2012 14:02
jonikDk, вот кусок макроса, в котором происходит добавление инфы в базу:


Код: v = "'" + n3 + "', '" + Telephones.Text + "', '" + CStr(Now) + "', '" + FIO.Text + "', '" + Profession.Text + k + ", " + nd + Komment.Text + "', CURRENT_USER, " + CStr(status) + "," + CStr(tip_kontakt)

s = "INSERT INTO CLIENT_CATALOG (ITEM_ID,ITEM_NAME,ITEM_CONTACTS,ITEM_DATA,ITEM_CONTACT_NAME,ITEM_CONTACT_PROFESSION,ITEM_KOMPLEKT,ITEM_DATA_NEXT,ITEM_KOMMENT,ITEM_USER,ITEM_STATUS,ITEM_TIP) " & _
"VALUES (GEN_ID(id_gen,1)," + v + ")"
rst.Open s, conn, adOpenDynamic, adLockOptimistic, auto_commit = True
Автор: jonikDk
Дата сообщения: 19.09.2012 14:19

Цитата:
Нужны ли здесь какие-то супергарантии? Я думаю, это излишне.

Ну как минимум, может быть ошибка в данных - слишком длинная строка.
Также могут быть и другие ошибки, при сохранении.


Цитата:
Я именно с такого вопроса и начал, но до сих пор так и не получил примера

Пожалуйста, пример.
Сделай своему пользователю интерфейс для удаления данных.
И забей на дырки в id, они все равно будут, такова практика многопользовательского режима.

Цитата:
Одно воспитание ...

Почему же, было пожелание, почитать доку, даже книгу посоветовали.
На этом я пожалуй прекращу "воспитание", каждый сам себе кузнец . Желающий услышать, да услышит...
Автор: Maximus777
Дата сообщения: 19.09.2012 14:38
jonikDk
Цитата:
Сделай своему пользователю интерфейс для удаления данных.

Пусть вводят внимательно, тогда не будет нужды удалять.


Цитата:
И забей на дырки в id, они все равно будут, такова практика многопользовательского режима.

Настоящие гусары не в силах забить на дырки
Автор: miwa
Дата сообщения: 19.09.2012 14:48
Maximus777
Кстати, а что будет, если вредный пользователь введет такой коментарий:

Текст коментария"; delete from client_catalog;

ну, скажем, из вредности? Или детальный комментарий на 32КБ - из старательности и исполнительности?
Автор: Maximus777
Дата сообщения: 19.09.2012 15:22
miwa

Цитата:
Кстати, а что будет, если вредный пользователь введет такой коментарий:
Текст коментария"; delete from client_catalog;




Цитата:
Или детальный комментарий на 32КБ - из старательности и исполнительности?

Исключено.
Автор: jonikDk
Дата сообщения: 19.09.2012 15:53

Цитата:
Пусть вводят внимательно, тогда не будет нужды удалять.

Так и создаются плохое мнение о программистах. Человек должен иметь право на ошибку, а также и на исправление этой ошибкой. Пользователь - это тоже человек. Программист должен предложить интерфейс для удаления. Если нельзя этот интерфейс давать всем делаете отдельное приложение, либо в своем приложении делаете отдельный режим для удаления, но обязательно с другими правами, чтобы ваш обычный пользователь, который вводит инфу не смог удалить.

Цитата:
Настоящие гусары не в силах забить на дырки

Настоящие гусары потому и настоящие, потому что они в первую очередь практики

Автор: Maximus777
Дата сообщения: 19.09.2012 16:27
jonikDk
Цитата:
Человек должен иметь право на ошибку

Я не отнимаю ни у кого это право.


Цитата:
также и на исправление этой ошибкой.

А вот это уже лишнее.


Цитата:
Если нельзя этот интерфейс давать всем делаете отдельное приложение, либо в своем приложении делаете отдельный режим для удаления, но обязательно с другими правами, чтобы ваш обычный пользователь, который вводит инфу не смог удалить.

Разве я не об этом же? "Отдельное приложение" - это триггер. Право удалять есть только у меня. Что я делаю не по рецепту? Кто-нить может набросок кода триггера для моей задачи выложить?
Автор: eddoc
Дата сообщения: 19.09.2012 17:14
Maximus777
Можно некоторые замечания?

Все сказанное выше про "бездырочную" нумерацию - результат огромного опыта наступания предыдущих поколений на бесчисленное количество граблей, разбросанных на этом тернистом пути.

Ваше нежелание осмысливать приведенные доводы приведет к тому, что упомянутый выше опыт вы приобретете в полном объеме и с наибольшими затратами. Сочувствую ...
Автор: Maximus777
Дата сообщения: 19.09.2012 17:43
eddoc
Цитата:
Все сказанное выше про "бездырочную" нумерацию - результат огромного опыта наступания предыдущих поколений на бесчисленное количество граблей, разбросанных на этом тернистом пути.

Заявляю с полной ответственностью, я это (опыт предыдущих поколений) учту.

А теперь можно кусочек кода?

Страницы: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465

Предыдущая тема: Сравнение двух строк


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.