The forum for ZeosLib 7.2 Report problems. Ask for help, post proposals for the new version and Zeoslib 7.2 features here. This is a forum that will be edited once the 7.2.x version goes into RC/stable!!
My personal intention for 7.2 is to speed up the internals as optimal a possible for all IDE's. Hope you can help?! Have fun with testing 7.2
procedure TZQueryClassesAdaptateur.SynchronizeApresSupression;
var
OldSQL: String;
sqltxt : String;
begin
try
with _query do
begin
OldSQL := SQL.Text;
SQL.Clear;
sqltxt := 'SET @VueGD := ''SELECT `gauche` AS `seq_number`, `idplan` FROM `DOCClassements` '+
'UNION SELECT `droit` AS `seq_number`, `idplan` FROM `DOCClassements'';';
SQL.Add(sqltxt);
sqltxt := 'UPDATE `DOCClassements` ' +
'SET `gauche` = ( SELECT COUNT(*) FROM @VueGD WHERE `idplan` = :idplan AND `seq_number` <= `gauche`), ' +
'`droit` = ( SELECT COUNT(*) FROM @VueGD WHERE `idplan` = :idplan AND `seq_number` <= `droit`) ' +
'WHERE `idplan` = :idplan;';
SQL.Add(sqltxt);
ParamByName('idplan').Value := _clsracine.idplan;
ExecSQL;
SQL.Text := OldSQL;
end;
except
On E: EDatabaseError do
begin
_query.SQL.Text := OldSQL;
TraitementErreurDatabase('Synchronize', E);
end;
end;
end;
Lazarus warm with a syntax error message next to 'SET `gauche` = ( SELECT COUNT(*) FROM @VueGD WHERE `idplan` = :idplan AND `seq_number` <= `gauche`)'...
two things come to my mind. I am not sure wether TZQuery will behave correctly if you want to execute more than one statement in one go with it. Better start an explicit transaction and execute each statement on its own, like this:
procedure TZQueryClassesAdaptateur.SynchronizeApresSupression;
var
OldSQL: String;
sqltxt : String;
begin
try
with _query do
begin
OldSQL := SQL.Text;
Connection.StartTransaction;
try
SQL.Text := 'SET @VueGD := ''SELECT `gauche` AS `seq_number`, `idplan` FROM `DOCClassements` '+
'UNION SELECT `droit` AS `seq_number`, `idplan` FROM `DOCClassements`';
ExecSQL;
SQL.Text := 'UPDATE `DOCClassements` ' +
'SET `gauche` = ( SELECT COUNT(*) FROM @VueGD WHERE `idplan` = :idplan AND `seq_number` <= `gauche`), ' +
'`droit` = ( SELECT COUNT(*) FROM @VueGD WHERE `idplan` = :idplan AND `seq_number` <= `droit`) ' +
'WHERE `idplan` = :idplan;';
ParamByName('idplan').Value := _clsracine.idplan;
ExecSQL;
Connection.Commit;
except
Connection.Rollback;
raise;
end;
SQL.Text := OldSQL;
end;
except
On E: EDatabaseError do
begin
_query.SQL.Text := OldSQL;
TraitementErreurDatabase('Synchronize', E);
end;
end;
end;
Second: it seems that in your second statement you use a user variable for a table name. The MySQL documantation says:
MySQL 5.7 Reference Manual, 10.4 User-Defined Variables wrote:User variables are intended to provide data values. They cannot be used directly in an SQL statement as an identifier or as part of an identifier, such as in contexts where a table or database name is expected...
So I assume, your subselects will fail anyway. You probably will have to transfer @VueGD to your program and create the second statement according to the result of your first statement.
I didn't intend to tell you that Zeos doesn't support what you do. I wanted to tell you, that in your second SQL statement, the use of @VueGD might be incorrect, if I understand the MySQL manual (MySQL 5.7 Reference Manual, 10.4 User-Defined Variables) correctly. If you are sure, that your SQL is correct then Zeos will support you in getting your job done.
From a Zeos POV this is a limitation of MySQL. @VueGD is a user defined Variable. In MySQL one can't reference result sets or some kind of instant views with user defined Variables. Your current solution uses VueGD as a subselect and not as a view.