powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Ошибка при вставке записи в FIBPLus Dataset
8 сообщений из 8, страница 1 из 1
Ошибка при вставке записи в FIBPLus Dataset
    #39642346
Logos300
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Привествую! С днём Победы!
Использую Delphi XE5 и FIBPLus 7.5.
Пытаюсь вставить данные из формы в базу, вот код:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
procedure TfmAddNewFizClient.bApplyClick(Sender: TObject);
var
  Sername: string;
  Name: string;
  LastName: string;
  PassportSeria: string;
  PassportNumber: string;
  Birthday: string;
  BirthdayPlace: string;
  WhoGivePassp: string;
  PassportDate: string;
  AdressReg: string;
  AdressLive: string;
  Phone: string;
  Email: string;
begin
  //Инициализация переменных
  Sername:=trim(edClientSername.Text);
  Name:=trim(edClientName.Text);
  LastName:=trim(edClientLastName.Text);
  PassportSeria:=trim(edPassportSeria.Text);
  PassportNumber:=trim(edPassportNumber.Text);
  Birthday:=trim(medClientBirthday.Text);
  BirthdayPlace:=trim(edBirthdayPlace.Text);
  WhoGivePassp:=trim(edWhoGivePassport.Text);
  PassportDate:=trim(medPassportDate.Text);
  AdressReg:=trim(mRegAdress.Text);
  AdressLive:=trim(mLiveAdress.Text);
  Phone:=trim(medPhone.Text);
  Email:=trim(edEmail.Text);
  //Вставка и запись данных в БД
  fmFizClients.fbFizClientsDataSet.InsertSQL.Clear;
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add('INSERT INTO T_FIZ_CLIENTS (');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add('ID_CLIENT_VID,');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add('SERNAME,');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add('NAME,');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add('LAST_NAME,');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add('PASSPORT_SERIA,');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add('PASSPORT_NUMBER,');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add('BIRTHDAY,');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add('BIRTHDAY_PLACE,');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add('WHO_GIVE_PASSP,');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add('PASSPORT_DATE,');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add('ADRESS_REG,');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add('ADRESS_LIVE,');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add('PHONE,');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add('EMAIL');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add(')VALUES(');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add('1,');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add(Sername + ',');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add(Name + ',');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add(LastName + ',');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add(PassportSeria + ',');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add(PassportNumber + ',');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add(Birthday + ',');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add(BirthdayPlace + ',');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add(WhoGivePassp + ',');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add(PassportDate + ',');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add(AdressReg + ',');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add(AdressLive + ',');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add(Phone + ',');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add(Email + ',');
  fmFizClients.fbFizClientsDataSet.InsertSQL.Add(');');
  fmFizClients.fbFizClientsDataSet.Insert;
  fmFizClients.fbFizClientsDataSet.Post;
  ShowMessage('УСПЕШНО!!!');
end;



После отработки процедуры выдается ошибка:



Я начинающий, прошу помочь :) Я вычислил, что Делфи материться на первое значение-дату, но не могу понять в чём дело :)
...
Рейтинг: 0 / 0
Ошибка при вставке записи в FIBPLus Dataset
    #39642348
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Logos300,

используй подготовленные запросы, читай про параметры.
Обычно в датасете SelectSql, InsertSql, UpdateSql, DeleteSql и RefreshSql инициализируются ровно один раз. Если начинающий делай это с помощью мастеров компонентов.
...
Рейтинг: 0 / 0
Ошибка при вставке записи в FIBPLus Dataset
    #39642357
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Logos300,

Про параметризированные запросы тубе указали все правильно, но ошибка, в принципе, в том, что в таком виде вставляемые значения должны быть в кавычках и даты тоже. Причем даты не посто в кавычках, но и в определенном формате. Через параметры поэтому все получается гораздо проще. И отлаживайся в таких случаях на более простых запросах, из двух полей, а не из двадцати двух.
...
Рейтинг: 0 / 0
Ошибка при вставке записи в FIBPLus Dataset
    #39642358
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Logos300,

"вставляемые строковые значения и значения дат должны быть в кавычках".
...
Рейтинг: 0 / 0
Ошибка при вставке записи в FIBPLus Dataset
    #39642427
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Logos300 fmFizClients.fbFizClientsDataSet.Insert;
научись пользоваться отладчиком. Вот прямо перед ЭТИМ оператором посмотри, что уже находится
в insertsql, и насколько оно соответствует SQL.
Logos300Я начинающий
отладчик, отладчик, и еще раз отладчик.
...
Рейтинг: 0 / 0
Ошибка при вставке записи в FIBPLus Dataset
    #39642428
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Logos300,

1. Значение 1-го же строкового поля без кавычек, дальше не смотрел.
2. Надо выкинуть это всё, и работать чз параметры, ссылки уже дали.
...
Рейтинг: 0 / 0
Ошибка при вставке записи в FIBPLus Dataset
    #39642430
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock,

На самом деле ссылок не давали. Давали типа умные советы.
...
Рейтинг: 0 / 0
Ошибка при вставке записи в FIBPLus Dataset
    #39642443
fraks
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наблюдаю в коде нелепое сочетание двух противоположных подходов к работе с базой.
Это - использование датасета и вставка записи через его InsertSQL, при том что ввод данных производится из НЕ DataAware-контролов.
Да еще и из другой формы.
Да еще и перезаписывая этот самый InsertSQL каждый раз новым текстом,
да еще и без параметров.

Я исповедую отказ от DataAware подхода.
Поэтому я бы положил прямо на форму TfmAddNewFizClient компоненты транзакции и QIns : TFIBQuery (который НЕ датасет), и выполнял запрос непосредственно тут.
После закрытия текущей формы мы скорее всего попадаем в fmFizClients, посему функция которая создает открывает и выполняет окно fmAddNewFizClient у меня возвращает True/False, где True - запись вставлена, соответственно по выходу список нужно отрефрешить.
В var-парамере можно передать обратно и код вставленной записи что бы отрефрешив можно было спозиционироваться на только что вставленную запись.

Переменные которые тут заводятся - нафиг не нужны. Удобства не добавляют.

Текст SQL-запроса заполняется на стадии DesignTime и в RunTime не изменяется.

Соответственно, метод выглядел бы примерно так:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
procedure TfmAddNewFizClient.bApplyClick(Sender: TObject);
begin
  QIns.ParamByName('SERNAME'        ).AsString := trim( edClientSername.Text  );
  QIns.ParamByName('NAME'           ).AsString := trim( edClientName.Text     );
  QIns.ParamByName('LAST_NAME'      ).AsString := trim( edClientLastName.Text );
  QIns.ParamByName('PASSPORT_SERIA' ).AsString := trim( edPassportSeria.Text  );
  QIns.ParamByName('PASSPORT_NUMBER').AsString := trim( edPassportNumber.Text );
  QIns.ParamByName('BIRTHDAY'       ).AsString := trim( medClientBirthday.Text);
  QIns.ParamByName('BIRTHDAY_PLACE' ).AsString := trim( edBirthdayPlace.Text  );
  QIns.ParamByName('WHO_GIVE_PASSP' ).AsString := trim( edWhoGivePassport.Text);
  QIns.ParamByName('PASSPORT_DATE'  ).AsString := trim( medPassportDate.Text  );
  QIns.ParamByName('ADRESS_REG'     ).AsString := trim( mRegAdress.Text       );
  QIns.ParamByName('ADRESS_LIVE'    ).AsString := trim( mLiveAdress.Text      );
  QIns.ParamByName('PHONE'          ).AsString := trim( medPhone.Text         );
  QIns.ExecQuery;
  Fid := QIns.FieldByName('ID').AsInteger;
  QIns.Transaction.Commit;
  ShowMessage('Ok');
  ModalResult := True;
end;



Дальше есть вопросы к именованию компонент.
Какие-то контролы начинаются с "ed"? какие-то с "med" а какие-то с "m" - нет единообразия.
Дату я бы вводил и сохранял не текстом а датой, это позволит как минимум отфильтровать какой-нибудь бред еще на стадии ввода.
Многострочные данные я бы в varchar так сразу не пихал. А они вообще нужны, многострочные? (это я предполагаю что компоненты типа mLiveAdress - это не Edit а Memo).

Обработки ошибок тут так же нет.

Текст запроса в компоненте выглядит так:

QIns.SQL =
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
-- fmAddNewFizClient.QIns
--
-- Вставка в справочник нового клиента
--

execute block
returns(id integer)
as begin
  id = gen_id(gen_emp_id, 1);
  INSERT INTO T_FIZ_CLIENTS(
   ID,  SERNAME,  NAME,  LAST_NAME,  PASSPORT_SERIA,  PASSPORT_NUMBER,  BIRTHDAY,  BIRTHDAY_PLACE,  WHO_GIVE_PASSP,  PASSPORT_DATE,  ADRESS_REG,  ADRESS_LIVE,  PHONE)
  values (
  :ID, :SERNAME, :NAME, :LAST_NAME, :PASSPORT_SERIA, :PASSPORT_NUMBER, :BIRTHDAY, :BIRTHDAY_PLACE, :WHO_GIVE_PASSP, :PASSPORT_DATE, :ADRESS_REG, :ADRESS_LIVE, :PHONE);
  suspend;
end
';



Имя формы и компонента запроса указываю в первой строке для того что бы потом в таблицах мониторинга было проще ориентироваться откуда этот запрос выполняется.
В запросе сначала получается новый ID (имя генератора вставлено от балды), запись вставляется, а ID возвращается обратно.
Сейчас есть такая штука как RETURNING, но я не использую. Поддерживает ли эту штуку FIB+ - не в курсе.

Сразу про будущие грабли.
Юзер может ввести в поле текст длиннее чем поле в базе - при вставке возникнет исключение.
Лучше всего прямо в Edit ограничить максимальную длину разрешенную для ввода, через Edit.
Формы создания я не использую. Вставка записи у меня производится пустой, а потом она открывается на редактирование, с чтением данных из базы. А в запросе чтения можно прочитать длину поля и ограничить Edit, примерно такой процедурой

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
procedure FieldToControl(AEdit:TEdit; FN: string; Q: TpFIBQuery); overload;
begin
  AEdit.Text      := Q.FN(FN).AsString;
  AEdit.MaxLength := Q.FN(FN).Size;
end;

...
  FieldToControl(QSel, 'NAME', edClientName);
...



Ну и так далее.

Удачи.
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Ошибка при вставке записи в FIBPLus Dataset
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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