Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 多语句查询(Zeos)错误_Mysql_Delphi_Delphi Xe3_Zeos - Fatal编程技术网

Mysql 多语句查询(Zeos)错误

Mysql 多语句查询(Zeos)错误,mysql,delphi,delphi-xe3,zeos,Mysql,Delphi,Delphi Xe3,Zeos,我正在尝试进行如下的多语句查询: // without the second insert the query works fine. // i need 2 querys to work because later, i'll do inserts on different kind of tables. // that's why i need 2 querys, not a single query which insert 2 records. with ZQuery1 do

我正在尝试进行如下的多语句查询:

// without the second insert the query works fine.
// i need 2 querys to work because later, i'll do inserts on different kind of tables.
// that's why i need 2 querys, not a single query which insert 2 records.   

with ZQuery1 do
    begin
        SQL.Clear;
        SQL.Add('insert into client (name,age) values ('+QuotedStr('john')+','+QuotedStr('20')+');');
        SQL.Add('insert into client (name,age) values ('+QuotedStr('doe')+','+QuotedStr('21')+');');
        ExecSQL;
    end;
我收到了这个错误消息:SQL错误:您的SQL语法有错误;检查与您的MySQL服务器版本对应的手册,了解第2行的“插入到客户端(名称、年龄)值('doe','21')”附近使用的正确语法

我已经检查了手册,组件TZQuery和TZUpdateSql(来自zeos lib)提供了在内部执行多个语句的可能性

编辑[已解决] 谢谢你,GregD,在运行了几个测试之后,事务对我来说很好! 这就是我在未来帮助他人的方式

try
    ZConnection.AutoCommit := True;
    ZConnection.StartTransaction;
    
    With ZQuery Do
    begin
        SQL.Clear;
        SQL.Add('insert into clients (name,age) values ('+QuotedStr('john')+','+QuotedStr('20')+')');
        ExecSQL;
        SQL.Clear;
        SQL.Add('insert into clients (name,age) values ('+QuotedStr('doe')+','+QuotedStr('21')+')');
        ExecSQL;
    end;
    
    ZConnection.Commit; 
except
    ZConnection.Rollback
end;
这就是自动提交属性在Zeos中的实际工作方式:

AutoCommit为True时,事务将在每个执行的SQL语句后自动提交,但您可以明确地使用StartTransaction命令来防止这种自动提交,直到您明确地调用Commit

自动提交为False时,不应调用StartTransaction。然后事务会自动启动,但不会在每次执行语句后自动提交

过程StartTransactionStartTransaction过程在连接的数据库中启动新事务。仅当“自动提交”属性为TRUE时才应使用它。当您尝试在自动提交设置为false的情况下调用它时,将引发SinvalidopInnoutoCommit。这种行为是预期的,因为StartTransaction应被用作自动提交模式的转义。当您调用StartTransaction时,自动提交将“关闭”,然后,当您调用Commit或Rollback时,自动提交将再次“打开”。如果将“自动提交”设置为false,则会自动创建新事务,并选择关闭它们的方式(提交或回滚)

过程提交将当前语句提交到数据库。应仅在非自动提交模式下使用(其中每个语句都是自动提交的,使此过程无效),或在自动提交模式下并希望完成StartTransaction过程打开的事务时使用。提交完成当前事务(如果有)。如果不想将satatement保存到数据库,则应使用回滚过程


过程回滚回滚当前事务中以前的所有语句。应仅在非自动提交模式下使用(其中每个语句都是自动提交的,使此过程无效),或在自动提交模式下并希望完成StartTransaction过程打开的事务时使用。回滚完成当前事务(如果有)。如果您不想丢失您的satatement,您应该使用提交过程。

尝试此代码,如果出现相同的问题,请告知我们:

with ZQuery1 do
begin
    SQL.Clear;
    SQL.Add('insert into client (name,age) values ('+QuotedStr('john')+','+QuotedStr('20')+'),('+QuotedStr('doe')+','+QuotedStr('21')+');');
    ExecSQL;
end;
通过这种方式,您还可以加快MySQL对这个
INSERT
查询的处理速度,就像它在一个批处理中而不是两次处理一样

编辑#1:

我不是Zeos方面的专家,但对于其他语言,您可以尝试逐个执行查询:

with ZQuery1 do
    begin
        SQL.Clear;
        SQL.Add('insert into client (name,age) values ('+QuotedStr('john')+','+QuotedStr('20')+');');
        ExecSQL;
        SQL.Clear;
        SQL.Add('insert into client (name,age) values ('+QuotedStr('doe')+','+QuotedStr('21')+');');
        ExecSQL;
    end;
编辑#2:交易


有很多关于在MySQL中使用事务的好例子。尽管这些示例是为PHP编写的,但我相信您可以在那里找到一些好的指针。确保MySQL服务器上的表是
InnoDB
而不是
MyISAM

我也不是ZEOS方面的专家,但是看看,您是否将
TZUpdateSQL
Multistatement
属性设置为true?

我不知道ZEOS和多个语句,但这不是真正的问题。您的查询(SQL注入)和执行它们的缓慢方法(无法缓存和重用的连接字符串)造成了一个重大的安全问题

如果您正确地停止使用字符串连接来形成查询,而是使用参数化语句,则根本不需要担心多个语句:

with ZQuery1 do
begin
  SQL.Clear;
  SQL.Add('insert into client (name,age)');
  SQL.Add('values (:Name, :Age);'
  ParamByName('Name').AsString := 'John';
  ParamByName('Age').AsInteger := 20;
  ExecSQL;
  ParamByName('Name').AsString := 'Doe';
  ParamByName('Age').AsInteger :- 21;
  ExecSQL;
end;

现在查询将运行得更快(因为DBMS可以编译它一次并多次重复使用它(我提到的“缓存”),您不再有SQL注入风险,也不再需要多个语句。

您尝试过TZSQLProcessor吗?说该组件是为这种需要而设计的(如在ZSqlProcessor.pas单元中):


OT:如果您正在使用Delphi或RAD Studio的Enterprise、Ultimate或Architect版,请尝试。没有第二次插入,这是否有效?是的,没有第二次插入,它就像一个符咒:)我总是想知道是谁愚蠢地发起了这个丑陋的
SQL.Clear;SQL.Add(…)模式,而不是较短的
SQL.Text:='…'
。像所有愚蠢的事情一样,它的持久性是荒谬的。你的答案是可行的,很好,但问题是关于使用多个insert语句。。。但是很好的尝试:)是的,但是他的DBA可能更喜欢多行
INSERT
语句;-)说得好。我同意。实际上我自己也有这个问题,不确定Zeos是否支持多个查询。我现在没有在Linux操作系统上测试它。多重查询可以使用它吗?只是好奇。谢谢哦,你的答案是+1。@Rebelss,为什么不使用事务呢?事务是ACID兼容的,可以确保执行完全完成。@Rebelss我不是Zeos专家,但从概念上讲,我认为多个插入查询不能解决连接丢失的问题。相反,正如GregD所建议的,使用事务似乎是最合适的。在事务就绪的情况下,即使它们是多个执行语句也不重要。+1是解决OP问题以及其他潜在问题的最佳答案。这是否等于
insert-into-client(name,age)值(:Name1,:Age1),(:Name2,:Age2)
就速度而言?@SAMPro:这取决于。你得自己测试一下。SQL是以
{**
  Implements a unidatabase component which parses and executes SQL Scripts.
}