Простая БД на SQLite

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

EatMyShorts
А в каком компоненте данные редактируются непосредственно? Т.е. где шалят Ваши ручки? :)
Аватара пользователя
wofs
постоялец
Сообщения: 379
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань
Контактная информация:

Сообщение wofs »

транзация...

Код: Выделить всё

SQLTransaction.Active:=True //открыть транзакцию

   with Q1 do begin
     close;
     sql.Clear;
     sql.Add('insert into table1 (name) values ('Dannie') ;'); //любой запрос на добавление/удаление/редактирование
     ExecSQL;
   end;   

SQLTransaction.Commit; //закрыть ее и принять изменения

и...

Код: Выделить всё

DBNavigator

зачем?

Добавлено спустя 1 минуту 42 секунды:
если редактируем в dbgrid, то как минимум нужно сделать запрос редактируемым (не смотрел, возможно ли в лазарус - по делфи сужу)
EatMyShorts
новенький
Сообщения: 30
Зарегистрирован: 06.10.2009 19:48:19

Сообщение EatMyShorts »

А в каком компоненте данные редактируются непосредственно? Т.е. где шалят Ваши ручки? :)

Опять я не все рассказал(болтун находка для шпиона :) )
Вообщем в DBGride выбираю запись, а содержимое нужного поля отображается(все корректно) в DBEdit, вот в нем и редактирую а потом жму Apply на DBNavigator и в DBGride содержимое поля меняется нормально.
Аватара пользователя
wofs
постоялец
Сообщения: 379
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань
Контактная информация:

Сообщение wofs »

глянул... в лазарус у квери нема такого свойства (RequestLive)... но это не значит, что невозможно... господа старожилы - ваш выход :)

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

Код: Выделить всё

procedure TForm1.dbEdit1Exit(Sender: TObject);
 var
 NeedNumber: Integer;
 begin
    NeedNumber := Q1.RecNo;  //запоминаем № редактируемой записи
       Transaction.Active:=True;
    with Q2 do begin
    close;
    sql.Clear;
    sql.Add('update table1 set Name=:Name where ID=:ID;');
    params.ParamByName('Name').Value:=dbEdit1.Text;
    params.ParamByName('ID').Value:=Q1.FieldByName('ID').AsString;
    ExecSQL;
   end;
   Transaction.Commit;
   with Q1 do begin
   Close;
   Open;
   end;
   Q1.RecNo := NeedNumber;  //восстанавливаем курсор на записи
 end;                                                             

Возможно не оптимально, но работает. А теперь, что не удалось сделать:
1.Перевести запрос в режим редактирования (возможно не реализовано, может плохо искал)
2. Не работает Refresh - выдает ошибку. приходится открывать/закрывать запрос.
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

wofs писал(а):в лазарус у квери нема такого свойства (RequestLive)... но это не значит, что невозможно... господа старожилы - ваш выход

Нужность этого свойства весьма сомнительна. Если почитать справку по Дельфи, то там написано, что это свойство делает датасет либо обновляемым, либо только для чтения. У нас уже есть свойство "Только для чтения" (ReadOnly) зачем нужно ещё одно? ;)
Аватара пользователя
wofs
постоялец
Сообщения: 379
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань
Контактная информация:

Сообщение wofs »

to Vadim
ReadOnly

я обратил на него внимание, оно по умолчанию False, только вот редактировать квери не получается...
и еще почему не работает Refresh ?
EatMyShorts
новенький
Сообщения: 30
Зарегистрирован: 06.10.2009 19:48:19

Сообщение EatMyShorts »

Продолжаем разговор :D :

Код: Выделить всё

    with Q1 do begin
    close;
    sql.Clear;
    sql.Add('insert into table1 (fistid,secondid,Name) values (:fid,:sid,:date) ;');
    params.ParamByName('fid').Value:=fid.Text;
    params.ParamByName('sid').Value:=sid.Text;
    params.ParamByName('date').Value:=edit1.Text;
    ExecSQL;
   end;

Как получить текст запроса с подставленными параметрами? пробовал вызывать prepare, получать свойство text после ExecSQL, всегда возвращает:

Код: Выделить всё

'insert into table1 (fistid,secondid,Name) values (:fid,:sid,:date) ;'
Аватара пользователя
wofs
постоялец
Сообщения: 379
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань
Контактная информация:

Сообщение wofs »

to EatMyShorts
Как получить текст запроса с подставленными параметрами?

простите, не осознал смысл вопроса... :?
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

EatMyShorts
В свойстве "Text" содержится именно свойство "Text", т.е. то, что Вы и писали. :) Запрос со значениями параметров посылается серверу.
А зачем Вам значения параметров? Вы не знаете, что засовываете в параметры? Вы ведь значения из Edit'ов берёте, я не ошибаюсь? Наверное проще прямо в Edit'ах и посмотреть. ;)

Добавлено спустя 10 минут 34 секунды:
wofs писал(а):только вот редактировать квери не получается...

А это зависит от типа запроса. Если запрос простой, т.е. из одно таблицы, без агрегатных функций, то и редактируйте его на здоровье, никакие специальные свойства для этого не нужны. Редактировать же сложный запрос Вам помешает сам сервер, т.е. можно до утра то ставить то снимать ReadOnly, толку от этого не будет. :)
wofs писал(а):и еще почему не работает Refresh ?

Надо код посмотреть. Так трудно сказать...
Аватара пользователя
wofs
постоялец
Сообщения: 379
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань
Контактная информация:

Сообщение wofs »

to Vadim
А это зависит от типа запроса. Если запрос простой, т.е. из одно таблицы, без агрегатных функций,

про это я в курсе.. только вот парадокс в том, что не получается редактировать просто запрос выборка из одной таблицы.
Надо код посмотреть. Так трудно сказать..

да собственно примитив (пример можно взять из ссылки в моем предыдущем сообщении)

Код: Выделить всё

with do Query1 begin
close;
add "select * from table1 ;";
open;
end;
///
with do QueryEdit begin
close;
add "insert  into table1 values(Name) ;";
ExecSQL;
end;
Query1.Refresh; // не работает
{
хотя
Query1.Close;
Query1.Open;
отрабатывает
}

БД
Sqlite3
Lazarus 0/9/28
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

Что такое транзакции знаете?
EatMyShorts
новенький
Сообщения: 30
Зарегистрирован: 06.10.2009 19:48:19

Сообщение EatMyShorts »

Друзья, поведайте пожалуйста, как вы при программировании БД реализуете механизм отката изменений?(если оно вообще надо)
К примеру вставили мы в таблицу запись, а затем подумали и решили отменить эту операцию. Это дело можно возложить на пользователя, чтобы он нашел только что вставленную запись и удалил ее(но записей может быть ведь очень много). Или же запоминать индексы вставленных записей и по требованию пользователя производить отмену вставки (удаление по индексу). А как быть с обновлением записей?(UPDATE) Запоминать перед обновлением все поля записи? А ведь они могут быть очень большими. Поделитесь пожалуйста своим опытом в этом.
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

EatMyShorts писал(а):Друзья, поведайте пожалуйста, как вы при программировании БД реализуете механизм отката изменений?(если оно вообще надо)

Мы делаем отмену только тогда, когда без этого никак не обойтись. И для этого случая транзакции - это как раз то, что доктор прописал. :)
Отмены не должно быть много. Иначе это не отмена, а неправильное заполнение БД.
EatMyShorts
новенький
Сообщения: 30
Зарегистрирован: 06.10.2009 19:48:19

Сообщение EatMyShorts »

У меня приложении сделано так:

Код: Выделить всё

procedure InsertRecord(field1, field2, field3: string);
begin
  try
    transac.Active := True;
    with query do
    begin
      Close();
      SQL.Clear;
      SQL.Add(
        'INSERT INTO table1(f1, f2l, f3) '
        + 'VALUES(:field1, :field2, :field3)');
      Params.ParamByName('field1').AsString    := field1;
      Params.ParamByName('field2').AsString    := field2;
      Params.ParamByName('field3').AsString    := field3;
      ExecSQL;
    end;
    transac.Commit;
  except
    on E: Exception do
      MessageDlg(E.message, mtError, [mbOK], 0); 
end;

Как я понимаю откатить вставку, если она прошла успешно с помощью transac.RollBack не получится. Но если не производить Commit, то пользователь не увидит результат своего действия. Еще нашел что в дельфи используется так называемое кеширование изменений, т.е. изменеия производятся над локальной копией данных. А затем эти изменения либо сохраняются либо отменяются. Как с этим делом обстоит в lazarus?
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

EatMyShorts писал(а):Как я понимаю откатить вставку, если она прошла успешно с помощью transac.RollBack не получится.

Чтобы иметь возможность откатить транзакцию, её надо начать перед проведением какой-либо операцией над базой в явном виде.
Ответить