powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Как не допустить попадание дублей в таблицу БД?
15 сообщений из 15, страница 1 из 1
Как не допустить попадание дублей в таблицу БД?
    #39654354
Logos300
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
  //Проверка на то, что вносимое Физ. лицо уже есть в БД
  // Отдельно хватаем текущее значение Первичного ключа для Клиента:
  Curr_ID_CLIENT:=fmClients.fbClientsDataSet.FieldByName('ID_CLIENT').AsLargeInt;

  SQL:='SELECT COUNT(FIZ_SERNAME) FROM T_CLIENTS WHERE FIZ_PASSPORT_SERIA= ''' + PassportSeria + ''' AND  FIZ_PASSPORT_NUMBER= ''' + PassportNumber + '''';
  fbQuery.Close;
  fbQuery.Database:=fmClients.fbDatabase;
  fbQuery.Database.Connected:=true;
  fbQuery.SQL.Clear;
  fbQuery.SQL.Text:=SQL;
  fbQuery.ExecQuery;

ShowMessage(IntToStr(fbQuery.RecordCount));

if (fbQuery.RecordCount>1) then
   begin
    MessageDlg('Возникла ошибка. Клиент с введёнными Серией/Номером паспорта уже есть в базе данных!', mtError, [mbOK],0);
    edPassportSeria.SetFocus;
    fbQuery.Database.Connected:=false;
    exit;
  end
  else
// далее – изменение данных в таблице



Фишка в том, что в БД, в таблице T_CLIENTS, есть два клиента с одинаковыми сериями и номерами паспортов, но строка:

Код: pascal
1.
ShowMessage(IntToStr(fbQuery.RecordCount));



Упорно выдаёт, что записей, удовлетворяющих SQL-запросу всего 1. В чем я ошибся?
...
Рейтинг: 0 / 0
Как не допустить попадание дублей в таблицу БД?
    #39654359
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Logos300В чем я ошибся?

Много в чём.

Помимо всего прочего: RecordCount возвращает число записей, отфетченных на клиента. В
твоём случае он никогда не вернёт число больше единицы.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как не допустить попадание дублей в таблицу БД?
    #39654361
m7m
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Logos300,

Не страдай проверкой этого факта в клиенте, при таком подходе рано иди поздно появятся "два клиента с одинаковыми сериями и номерами паспортов"

В таблице T_CLIENTS создай уникальный ключ по полям серия и номер паспорта
...
Рейтинг: 0 / 0
Как не допустить попадание дублей в таблицу БД?
    #39654362
AltHasp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Logos300,

- Наверное лучше использовать параметризированные запросы;
- функция Exists работает быстрее;
- для контроля " попадание дублей в таблицу БД" - можно юзать связку триггер+исключения;
- уникальный индекс по вашим двум полям также может помочь;
...
Рейтинг: 0 / 0
Как не допустить попадание дублей в таблицу БД?
    #39654365
fraks
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сначала запрос лучше всего отлаживать отдельно, в IBExpert например, и только потом переносить в приложение.
Запрос вида

Код: plsql
1.
SELECT COUNT(...) FROM



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

Код: pascal
1.
fbQuery.RecordCount;

выдает количество записей, возвращенных запросом, причем даже в этом есть еще масса тонкостей, в зависимости от ситуации.

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

Код: pascal
1.
fbQuery.Fields[0].AsInteger



Собирать текст запроса в рантайме - некошерно.
Например такой минус - если внутри текстового поля PassportSeria или PassportNumber оператор введет символ ' - запрос не выполнится, будет ошибка.
Гораздо лучше пользоваться параметрами. В этом случае никаких проблем со значением параметров не будет.

Код: plsql
1.
2.
3.
4.
SELECT COUNT(FIZ_SERNAME) 
FROM T_CLIENTS 
WHERE (FIZ_PASSPORT_SERIA  = :PassportSeria)
  AND (FIZ_PASSPORT_NUMBER = :PassportNumber)



Этот текст запроса прописать в свойство Query.SQL в дизайн-тайме, заполнять параметры вот так:

Код: pascal
1.
2.
3.
4.
fbQuery.ParamByName('PassportSeria' ).AsInteger := PassportSeria;
fbQuery.ParamByName('PassportNumber').AsInteger := PassportNumber;
fbQuery.ExecQuery;
i := fbQuery.Fields[0].AsInteger;
...
Рейтинг: 0 / 0
Как не допустить попадание дублей в таблицу БД?
    #39654367
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AltHasp> - функция Exists работает быстрее;
> - для контроля " попадание дублей в таблицу БД" - можно юзать связку триггер+исключения;
> - уникальный индекс по вашим двум полям также может помочь;

В обратном порядке. Сначала индекс, потом
триггер, потом все остальные варианты проверок.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как не допустить попадание дублей в таблицу БД?
    #39654368
fraks
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если в базе создать ограничение уникальности на такую комбинацию значений - то дубль вставить будет невозможно из любого приложения, проверяет оно на дубль или нет.
Остается только грамотно поймать и отобразить попытку нарушения уникальности, что бы оператор понял в чем проблема.

Код: plsql
1.
ALTER TABLE T_CLIENTS ADD CONSTRAINT T_CLIENTS_UNI UNIQUE (FIZ_PASSPORT_SERIA, FIZ_PASSPORT_NUMBER);
...
Рейтинг: 0 / 0
Как не допустить попадание дублей в таблицу БД?
    #39654370
fraks
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AltHasp- для контроля " попадание дублей в таблицу БД" - можно юзать связку триггер+исключения;

Это плохой метод, он не гарантирует отсутствие дублей.
Триггер работает в контексте транзации - он может не видеть уже вставленную запись-дубль.

AltHasp- уникальный индекс по вашим двум полям также может помочь;

Это IMHO единственный надежный метод.
Впрочем, эта надежность иногда мешает, ее не получится обойти, а реальный мир иногда может потребовать наличие дублей.
Зависит от проектирования БД.
...
Рейтинг: 0 / 0
Как не допустить попадание дублей в таблицу БД?
    #39654375
rdb_dev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Предполагаю, что ты ошибся в создании ограничений на таблицу, хранящую данные о серии и номере паспорта.
...
Рейтинг: 0 / 0
Как не допустить попадание дублей в таблицу БД?
    #39654380
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fraks> Триггер работает в контексте транзации - он
fraks> может не видеть уже вставленную запись-дубль.

Это зависит от того, как транзакции запрограммировать.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как не допустить попадание дублей в таблицу БД?
    #39654382
fraks
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов Рустамfraks> Триггер работает в контексте транзации - он
fraks> может не видеть уже вставленную запись-дубль.

Это зависит от того, как транзакции запрограммировать.

Как ни программируй, а незакоммиченную запись все равно не увидеть.
...
Рейтинг: 0 / 0
Как не допустить попадание дублей в таблицу БД?
    #39654386
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Незакоммиченную обычно и не надо.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как не допустить попадание дублей в таблицу БД?
    #39654389
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гаджимурадов РустамНезакоммиченную обычно и не надо.Ну вот. Две транзакции не увидели одинаковой незакоммиченной записи, и вставили каждая такую.
...
Рейтинг: 0 / 0
Как не допустить попадание дублей в таблицу БД?
    #39654449
AltHasp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fraks,

Код: pascal
1.
fbQuery.ParamByName('PassportSeria' ).AsInteger := PassportSeria;




м.б.
Код: pascal
1.
fbQuery.ParamByName('PassportSeria' ).AsString := PassportSeria;



т.к. серии обычно содержать и символьные идентификатор
...
Рейтинг: 0 / 0
Как не допустить попадание дублей в таблицу БД?
    #39654487
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AltHasp,

смотря где и когда. это раньше серия была типа 4 НК ... А сейчас там только цифры. Тем не менее, с этим все равно бардак. РЖД сливает и серию и номер в одно "число", без пробелов. А на самом деле серия - 2 по 2 цифры. В общем, лучше смотреть какую-нибудь официальную спецификацию.
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Как не допустить попадание дублей в таблицу БД?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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