Правильно ли делает StepAndReset в SQLite, что не генерирует

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

Ответить
SilverShadow
новенький
Сообщения: 22
Зарегистрирован: 10.03.2010 16:48:59

Правильно ли делает StepAndReset в SQLite, что не генерирует

Сообщение SilverShadow »

Exception?

Вот пример:

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

{$MODE DELPHI}

program test;

uses sysutils, SQLite3, SQLite3Wrap;

var dSQLite3Base01   : TSQLite3Database;
    dStmt      : TSQLite3Statement;

begin

  if not FileExists('MyBase.db3') then
   begin
     dSQLite3Base01 := TSQLite3Database.Create;
     try
       dSQLite3Base01.Open('MyBase.db3');
       dSQLite3Base01.Execute('CREATE TABLE testtable (fied_a TEXT, fied_b TEXT)');
       dSQLite3Base01.Execute('CREATE UNIQUE INDEX a_b ON testtable(fied_a, fied_b)');
     finally
       dSQLite3Base01.Free;
     end;

     writeln('base created.');
   end;

try
  dSQLite3Base01 := TSQLite3Database.Create;

    dSQLite3Base01.Open('MyBase.db3');

    dStmt := dSQLite3Base01.Prepare('INSERT INTO testtable (fied_a, fied_b) VALUES (?, ?)');

    try

      writeln('StepAndReset begin.');

      dStmt.BindText(1, '1AA');
      dStmt.BindText(2, '1BB');
      dStmt.StepAndReset;

      writeln('1');

      dStmt.BindText(1, '2AA');
      dStmt.BindText(2, '2BB');
      dStmt.StepAndReset;

      writeln('2');

      dStmt.BindText(1, '3AA');
      dStmt.BindText(2, '3BB');
      dStmt.StepAndReset;

      writeln('3');

      dStmt.BindText(1, '3AA');
      dStmt.BindText(2, '3BB');
      dStmt.StepAndReset;

      writeln('Again 3, must be exception!!!');


    except on E: Exception do
     writeln('exception catched, ', E.Message);
    end;


    dStmt.Free;

    writeln('StepAndReset done!');


    try
      writeln('trying illegal operation....');

      dSQLite3Base01.Execute('INSERT INTO testtable (fied_a, fied_b) VALUES ("1AA", "1BB")');

      writeln('after try.');

    except on E: Exception do
      writeln('exception catched, ', E.Message);
    end;

finally
  dSQLite3Base01.Free;
end;

end.

Использую обёртку SQLite3.pas из источника http://indasoftware.com/sqlite/, который ведёт на http://github.com/plashenkov/SQLite3-Delphi-FPC.
Во втором случае из примера exception отлично ловится, а в первом - нет. Я пока до этого дошёл, чуть голову не сломал. :evil: И что мне теперь, групповой операцией не пользоваться? Я, конечно, могу каждый раз в цикле давать саму команду INSERT INTO через .Execute, но как-то это неправильно, как мне кажется...
stanilar
постоялец
Сообщения: 289
Зарегистрирован: 09.03.2010 18:09:02

Сообщение stanilar »

Тут уже был недавно топик, в котором ТС просто не знал что SQlite не поддерживает foreignkey, пока эту поддержку не включишь явным образом. Отвечу примерно так-же как и в том топике:
SQLite это замена механизма readfile/writefile, а не простенькая бесплатная БД.

Сразу бросается в глаза, что в первом случае Вы работаете с паскалевской оберткой, а во втором выполняете прямое обращение к функциям SQLite. Или я не прав?
SilverShadow
новенький
Сообщения: 22
Зарегистрирован: 10.03.2010 16:48:59

Сообщение SilverShadow »

Сразу бросается в глаза, что в первом случае Вы работаете с паскалевской оберткой, а во втором выполняете прямое обращение к функциям SQLite. Или я не прав?

Нет, и в том и в другом случае идут обращения через обёртку. На самом деле в первом примере три итерации для наглядности, а в реальной программе - заполнение полей в цикле до момента окончания исходного файла.
SQLite это замена механизма readfile/writefile, а не простенькая бесплатная БД.

Тот функционал, который присущ SQLite, не позволяет мне согласиться с этим утверждением. Вы таким макаром все парадоксовские и .DBF'ные компоненты/модуля в замену readfile/writefile отправите пожалуй.
stanilar
постоялец
Сообщения: 289
Зарегистрирован: 09.03.2010 18:09:02

Сообщение stanilar »

SilverShadow писал(а):Тот функционал, который присущ SQLite, не позволяет мне согласиться с этим утверждением.

Это не мое утверждение, так написано в справке SQLIte.

Добавлено спустя 1 минуту 49 секунд:
Re: Правильно ли делает StepAndReset в SQLite, что не генерирует
И еще раз обращаю Ваше внимание на то, что бд'шный функционал, в некоторых случаях, надо включать ручками.
SilverShadow
новенький
Сообщения: 22
Зарегистрирован: 10.03.2010 16:48:59

Сообщение SilverShadow »

Хорошо, тогда я сформулирую вопрос иначе: знаете ли Вы, что именно надо "включить ручками", чтобы StepAndReset генерировал exception о нарушении уникальности индекса при добавлении записей в базу(а не молча ничего не делал)? И как Вы считаете, должен ли этот exception генерироваться в описанной мною ситуации, или то, что его(exception) нету - в порядке вещей(вне зависимости ото того, что "SQLite это замена механизма readfile/writefile")?
stanilar
постоялец
Сообщения: 289
Зарегистрирован: 09.03.2010 18:09:02

Сообщение stanilar »

Судя по поиску, в SqlIte нет функционала StepAndReset. Таки это программная обертка над SQLite API. А ведь я Вас спрашивал об этом.
Аватара пользователя
Снег Север
долгожитель
Сообщения: 3067
Зарегистрирован: 27.11.2007 15:14:47
Контактная информация:

Сообщение Снег Север »

В sqlite есть INSERT OR FAIL оператор, я его не проверял, но, возможно, он сгенерирует ошибку, которая вам нужна.
SilverShadow
новенький
Сообщения: 22
Зарегистрирован: 10.03.2010 16:48:59

Сообщение SilverShadow »

stanilar писал(а):Судя по поиску, в SqlIte нет функционала StepAndReset. Таки это программная обертка над SQLite API. А ведь я Вас спрашивал об этом.

Я, конечно, некропостер. Но вот недавно дошли руки в обёртке поковыряться. И вот что там есть:

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

function TSQLite3Statement.Step: Integer;
begin
  Result := sqlite3_step(FHandle);
end;

function TSQLite3Statement.StepAndReset: Integer;
begin
  Result := Step;
  Reset;
end;

function sqlite3_step(pStmt: PSQLite3Stmt): Integer; cdecl; external sqlite3_lib;
Т.е. TSQLite3Statement.Step - вызов внешней функции из DLL, а в StepAndReset к этой функции просто добавляется переинициализация для пакетного использования.
Таким образом, exception не генерируется библиотекой SQLite, что я считаю неправильным.
Ответить