* Fix bug #0036461, parameters not correctly refreshed in Mysql

git-svn-id: trunk@43702 -
This commit is contained in:
michael 2019-12-20 16:28:42 +00:00
parent 3440d166ae
commit b2957b92f4
2 changed files with 67 additions and 20 deletions

View File

@ -92,7 +92,10 @@ Type
TCursorName = Class(TSQLCursor)
protected
FRes: PMYSQL_RES; { Record pointer }
FStatement : String;
// Statement with param placeholders $1 $2 etc.
FPreparedStatement : String;
// Statement with param placeholders replaced with actual values.
FActualStatement : String;
Row : MYSQL_ROW;
Lengths : pculong; { Lengths of the columns of the current row }
RowsAffected : QWord;
@ -589,9 +592,9 @@ begin
// DatabaseError('Parameters (not) yet supported for the MySQL SqlDB connection.',self);
With Cursor as TCursorName do
begin
FStatement:=Buf;
FPreparedStatement:=Buf;
if assigned(AParams) and (AParams.count > 0) then
FStatement := AParams.ParseSQL(FStatement,false,sqEscapeSlash in ConnOptions, sqEscapeRepeat in ConnOptions,psSimulated,paramBinding,ParamReplaceString);
FPreparedStatement := AParams.ParseSQL(FPreparedStatement,false,sqEscapeSlash in ConnOptions, sqEscapeRepeat in ConnOptions,psSimulated,paramBinding,ParamReplaceString);
FPrepared:=True;
end
end;
@ -621,6 +624,7 @@ begin
mysql_free_result(C.FRes);
C.FRes:=Nil;
end;
C.FInitFieldDef:=True;
SetLength(c.MapDSRowToMSQLRow,0);
inherited;
end;
@ -648,18 +652,19 @@ begin
ParamNames[AParams.count-i-1] := C.ParamReplaceString+inttostr(AParams[i].Index+1);
ParamValues[AParams.count-i-1] := GetAsSQLText(AParams[i]);
end;
// paramreplacestring kan een probleem geven bij postgres als hij niet meer gewoon $ is?
C.FStatement := stringsreplace(C.FStatement,ParamNames,ParamValues,[rfReplaceAll]);
end;
C.FActualStatement := stringsreplace(C.FPreparedStatement,ParamNames,ParamValues,[rfReplaceAll]);
end
else
C.FActualStatement:=C.FPreparedStatement;
if LogEvent(detParamValue) then
LogParams(AParams);
if LogEvent(detExecute) then
Log(detExecute, C.FStatement);
Log(detExecute, C.FPreparedStatement);
if LogEvent(detActualSQL) then
Log(detActualSQL,C.FStatement);
Log(detActualSQL,C.FActualStatement);
if mysql_query(FMySQL,Pchar(C.FStatement))<>0 then
if mysql_query(FMySQL,Pchar(C.FActualStatement))<>0 then
begin
if not ForcedClose then
MySQLError(FMYSQL,SErrExecuting,Self)

View File

@ -31,6 +31,7 @@ type
private
FMyQ: TSQLQuery;
FPrepareCount:Integer;
procedure CreateAndFillIDField;
procedure DoAfterPost(DataSet: TDataSet);
Procedure DoApplyUpdates;
procedure DoCount(Sender: TSQLConnection; EventType: TDBEventType; const Msg: String);
@ -60,6 +61,7 @@ type
procedure TestReturningUpdate;
procedure TestMacros;
Procedure TestPrepareCount;
Procedure TestPrepareCount2;
end;
{ TTestTSQLConnection }
@ -761,40 +763,80 @@ begin
end;
end;
procedure TTestTSQLQuery.TestPrepareCount;
procedure TTestTSQLQuery.CreateAndFillIDField;
Var
I : Integer;
begin
with SQLDBConnector do
begin
TryDropIfExist('FPDEV2');
ExecuteDirect('create table FPDEV2 (id integer not null, constraint PK_FPDEV2 primary key(id))');
CommitDDL;
ExecuteDirect('insert into FPDEV2 (id) values (1)');
ExecuteDirect('insert into FPDEV2 (id) values (2)');
for I:=1 to 10 do
ExecuteDirect('insert into FPDEV2 (id) values ('+IntToStr(I)+')');
Connection.OnLog:=@DoCount;
Connection.LogEvents:=[detPrepare];
end;
end;
procedure TTestTSQLQuery.TestPrepareCount;
begin
CreateAndFillIDField;
try
With SQLDBConnector.Query do
begin
Unidirectional:=True; // Disable server index defs etc
UsePrimaryKeyAsKey:=False; // Idem
SQL.Text:='Select ID from FPDEV2 where (ID=:ID)';
UsePrimaryKeyAsKey:=False; // Disable server index defs etc
SQL.Text:='Select ID from FPDEV2 where (ID>=:ID) order by ID';
ParamByname('ID').AsInteger:=1;
Prepare;
AssertFalse('Not Prepared',SQLDBConnector.Query.Prepared);
Open;
AssertEquals('Correct record count param 1',1,RecordCount);
AssertEquals('Correct SQL executed, correct paramete: ',1,Fields[0].AsInteger);
AssertEquals('Correct record count param 1',10,RecordCount);
AssertEquals('Correct SQL executed, correct parameter: ',1,Fields[0].AsInteger);
Close;
AssertFalse('Still not prepared',SQLDBConnector.Query.Prepared);
ParamByname('ID').AsInteger:=2;
Open;
AssertEquals('Correct record count param 2',1,RecordCount);
AssertEquals('Correct record count param 2',9,RecordCount);
AssertEquals('Correct SQL executed, macro value changed: ',2,Fields[0].AsInteger);
Close;
AssertFalse('Still not prepared',SQLDBConnector.Query.Prepared);
end;
AssertEquals('Prepare called only once ',2,FPrepareCount);
finally
SQLDBConnector.Connection.OnLog:=Nil;
end;
end;
procedure TTestTSQLQuery.TestPrepareCount2;
begin
CreateAndFillIDField;
try
With SQLDBConnector.Query do
begin
UsePrimaryKeyAsKey:=False; // Disable server index defs etc
SQL.Text:='Select ID from FPDEV2 where (ID>=:ID) order by ID';
ParamByname('ID').AsInteger:=1;
Prepare;
AssertTrue('Prepared',SQLDBConnector.Query.Prepared);
Open;
AssertEquals('Correct record count param 1',10,RecordCount);
AssertEquals('Correct SQL executed, correct parameter: ',1,Fields[0].AsInteger);
Close;
AssertTrue('Still prepared',SQLDBConnector.Query.Prepared);
ParamByname('ID').AsInteger:=2;
Open;
AssertEquals('Correct record count param 2',9,RecordCount);
AssertEquals('Correct SQL executed, macro value changed: ',2,Fields[0].AsInteger);
end;
AssertEquals('Prepare called only once ',1,FPrepareCount);
finally
SQLDBConnector.Connection.OnLog:=Nil;
end;
end;