SQLite ExecuteDirect
Posted: 23.05.2023, 05:15
I assume that method
TZConnection.ExecuteDirect(const SQL: string)
should send SQL to DB-library "as is". Without "preparing statements". Without any parsing and modifications. Am I right?
This behavior is in TZPostgreSQLConnection.ExecuteImmediat:
For example, this will works as expected:
All three SQL statements will be executed, because SQL string will be send to libpq "as is".
But this will not work for SQLite. Only the first INSERT will be executed. Because currently method TZSQLiteConnection.ExecuteImmediat trying to prepare statement. This method use sqlite3_prepare_v2.
In earlier versions of ZeosLib this method used sqlite3_exec. I suggest it must looks like:
P.S.
ExecuteImmediat - is this a typo? Or this is not English? In English must be "Immediate".
TZConnection.ExecuteDirect(const SQL: string)
should send SQL to DB-library "as is". Without "preparing statements". Without any parsing and modifications. Am I right?
This behavior is in TZPostgreSQLConnection.ExecuteImmediat:
Code: Select all
procedure TZPostgreSQLConnection.ExecuteImmediat(const SQL: RawByteString;
LoggingCategory: TZLoggingCategory);
...
QueryHandle := FPlainDriver.PQexec(Fconn, Pointer(SQL));
...
Code: Select all
ZConnectionPostgreSQL.ExecuteDirect(
'INSERT INTO TestTable (Id, Val) VALUES (1, ''AAA'');' + LineEnding +
'INSERT INTO TestTable (Id, Val) VALUES (2, ''BBB'');' + LineEnding +
'INSERT INTO TestTable (Id, Val) VALUES (3, ''CCC'');' + LineEnding);
But this will not work for SQLite. Only the first INSERT will be executed. Because currently method TZSQLiteConnection.ExecuteImmediat trying to prepare statement. This method use sqlite3_prepare_v2.
In earlier versions of ZeosLib this method used sqlite3_exec. I suggest it must looks like:
Code: Select all
procedure TZSQLiteConnection.ExecuteImmediat(const SQL: RawByteString;
LoggingCategory: TZLoggingCategory);
var
Status: Integer;
LogSQL: String;
ErrorMessage: PAnsiChar;
begin
{$IFDEF UNICODE}
LogSQL := ZRawToUnicode(SQL, zCP_UTF8);
{$ELSE}
LogSQL := SQL;
{$ENDIF}
if Pointer(SQL) = nil then
Exit;
try
Status := FPlainDriver.sqlite3_exec(FHandle, Pointer(SQL), nil, nil, ErrorMessage);
if (Status <> SQLITE_OK) and (Status <> SQLITE_DONE) then
HandleErrorOrWarning(LoggingCategory, Status, LogSQL, IImmediatelyReleasable(FWeakImmediatRelPtr));
finally
if DriverManager.HasLoggingListener then
DriverManager.LogMessage(LoggingCategory, URL.Protocol, LogSQL);
end;
end;
ExecuteImmediat - is this a typo? Or this is not English? In English must be "Immediate".