powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Не давать вставить дубликат
15 сообщений из 15, страница 1 из 1
Не давать вставить дубликат
    #32384196
IgorL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hi, All!
Маленькая проблемка.
Есть табличка, одно из полей (ID) Not NULL, для его заполнения использую генератор и триггер на BI. Нужно обеспечить уникальность всех полей, кроме ID.
Создал индекс (UNIQUE) на все поля кроме ID, в принципе работает, запись не вставляет, но генератор всё равно инкрементится :( а этого бы не хотелось.
Код триггера на BI:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
  /* Trigger: PHONES_ID */ 
CREATE TRIGGER PHONES_ID FOR PHONES ACTIVE
BEFORE INSERT POSITION  0 
AS
begin
  IF (NEW.ID IS NULL) THEN
      NEW.ID = GEN_ID(PHONES_NEW_ID,  1 );
end

Предварително искать запись тоже не хочется - долго может получиться...
Подскажите плз. может кто уже делал подобное...
...
Рейтинг: 0 / 0
Не давать вставить дубликат
    #32384314
Серега
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дырки в ID не ндравятся? А чем они мешают? Если уж сильно надо - создай другое поле и нумеруй его посте вставки. ID оставь без изменений как ПК.
...
Рейтинг: 0 / 0
Не давать вставить дубликат
    #32384366
KeepeR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CREATE TRIGGER PHONES_ID FOR PHONES ACTIVE
BEFORE INSERT POSITION 0
AS
begin
IF (NEW.ID IS NULL) THEN NEW.ID = GEN_ID(PHONES_NEW_ID, 1);
end

Ты проматываешь генератор когда ID IS NULL !!! А потом задаешь такие вопросы !!!
...
Рейтинг: 0 / 0
Не давать вставить дубликат
    #32384392
KeepeR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CREATE TRIGGER PHONES_ID FOR PHONES ACTIVE
BEFORE INSERT POSITION 0
AS
begin
IF (NEW.ID IS NULL) THEN
попробуй вот это -->
NEW.ID = GEN_ID(PHONES_NEW_ID, 1);
заменить на это -->
NEW.ID = (SELECT MAX ID FROM PHONES) + 1

end

мне часто приходилось использовать такой принцип. Просто я пишу на Delphi + Interbase .... и делал это в Delphi. но принцип от этого не меняется.
...
Рейтинг: 0 / 0
Не давать вставить дубликат
    #32384412
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KeepeRпопробуй вот это -->
NEW.ID = GEN_ID(PHONES_NEW_ID, 1);
заменить на это -->
NEW.ID = (SELECT MAX ID FROM PHONES) + 1
И огребёшь по самый корешЁк в многопользовательском режиме.
Фи!
...
Рейтинг: 0 / 0
Не давать вставить дубликат
    #32384416
srf2000
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 KeepeR: нуну... ты сейчас насоветуешь... почитай лучше вот тут, особенно 3 пункт
http://www.ibase.ru/devinfo/dontdoit.htm
...
Рейтинг: 0 / 0
Не давать вставить дубликат
    #32384491
IgorL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А из триггера на AFTER INSERT к добавленной записи в FireBird 1.5 можно как нибудь добраться?
Идея такая:
Поле ID объявить как INTEGER DEFAULT 0
и в триггере на AFTER INSERT менять 0 на GEN_ID(PHONES_NEW_ID, 1).

Только как это сделать? NEW.ID = GEN_ID(PHONES_NEW_ID, 1) поле не меняет :(

на PHONES.ID = GEN_ID(PHONES_NEW_ID, 1) ругается типа нет переменной ID...
...В Оракле вроде можно было, хотя не помню :( давно дело было.
...
Рейтинг: 0 / 0
Не давать вставить дубликат
    #32384572
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В after insert модификация псевдопеременной " NEW " не оказывает влияния на значения вставленной строки.
Если ты таки хочешь поменять только-что вставленные значения, то в триггере after insert нужно выполнить обычный апдейт.
Код: plaintext
1.
2.
UPDATE PHONES
  SET ID = ...
WHERE ...

НО! К посталенной задаче это не имеет никакого отношения ;)
Без принудительного резервирования таблицы, при многопользовательской работе, дырки будут.
И даже при резервировании, они тоже могут возникнуть, если к примеру, возникнет потребность удалить пару записей.
Так что, имхо, " овчинка вычинки не сто ит"...
...
Рейтинг: 0 / 0
Не давать вставить дубликат
    #32384622
IgorL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо всем!
Решил.
Сделал так:
Поле ID сделал 0 по дефолту.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
IF (NEW.ID= 0 ) THEN
UPDATE PHONES
 SET ID = GEN_ID(PHONES_NEW_ID,  1 )
WHERE
 FIELD1 = NEW.FIELD1 and
 FIELD2 = NEW.FIELD2
......

и так по всем полям.

Задачка несколько спессфисская - в табличку пишет одна железяка через ODBC, читают многие, удалять из неё низзя, непрерывность поля ID тому лишнее подверждение.
Дубли же появлялись при сбоях на принимающей с железяки машине - железяка тогда из буффера вываливала все, не взирая на то, что половина уже принята и в базу прописана.

Дыры меня лично не пугали, у народа лишние вопросы появлялись :)
...
Рейтинг: 0 / 0
Не давать вставить дубликат
    #32384632
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IgorLДыры меня лично не пугали, у народа лишние вопросы появлялись :)
Если дыры не волнуют, то какая тогда разница, инкрементируется генератор, или нет? Чего ради?
...
Рейтинг: 0 / 0
Не давать вставить дубликат
    #32384712
IgorL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мимопроходящий
Если дыры не волнуют, то какая тогда разница, инкрементируется генератор, или нет? Чего ради?

OFF TOP
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
SELECT * FROM PHONES
WHERE DATE =  "20 . 01 . 04 "

ID      DATE    TIME            CALL                DURATION   EXT  ....
 222    20 . 01 . 04    14 : 05         8095XXXXXXXX       1 : 40 '20''    111  ....
229  20.01.04  14:05        838452XXXXX        0:20'10''     102   ....
..........

Вопрос заказчика - "Где ещё 7 записей???"
Ответ: "Генератор напрасно инкрементируется в случае попытки повторного инсерта существующей записи" будет неправильно понЯт :(
...
Рейтинг: 0 / 0
Не давать вставить дубликат
    #32384737
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Монопенисуально. Всё равно, если железяка сбойнёт, получишь дырку.
...
Рейтинг: 0 / 0
Не давать вставить дубликат
    #32384746
alex_k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ты в отчете генерируй нумерацию сам.
а показывать пользователю айди это дурной тон имхо.
...
Рейтинг: 0 / 0
Не давать вставить дубликат
    #32384789
IgorL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Господа!
Спасибо за ответы, приятно поражен скоростью и точностью их!

ТО Мимопроходящий:
Сбой железа - не моя проблема, у меня нумерация монотонно возрастает, то есть потерь на уровне софта, вроде, как будто, нет :)
Убеждать каждого, да ещё и в специфической (типа военной) организации ИМХО бесполезно.
Может даже и поймут, но сомнения останутся. Зачем мне это???

ТО alex_k :
К сожалению админ конторы в состоянии ручками набить SELECT * FROM ...
Выдавать при таком раскладе левую нумерацию, IMHO ещё хуже.
Другой вопрос всесто фактически автоинкремета можно забабашить какую нить мудрую уникальную последовательность... Да подлиннее ;) Типа MD5 из всех полей суммарно...
Но ЛЕНЬ. И зачем? И так неплохо.

Думаю темка себя исчерпала...
...
Рейтинг: 0 / 0
Не давать вставить дубликат
    #32385563
Серега
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Могу предложить еще один способ.
Писать с железки не в основную таблу, а в аналогичную буферную. По таймеру или по событию (например по количеству записей) переписывай данные в основную через ХП с предпроверкой уникальности, стирая ессно в буферной. Поскольку в этом случае писать может только эта ХП то пройдет способ с max(id)+1. Гоморойнее, конечно, но дыр не будет.
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Не давать вставить дубликат
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]