Reb*_*lss 4 mysql delphi zeos delphi-xe3
我试图像这样做一个多语句查询:
// 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;
Run Code Online (Sandbox Code Playgroud)
我收到此错误消息:SQL错误:您的SQL语法中有错误; 检查与您的MySQL服务器版本相对应的手册,以便在第2行的'insert into client(name,age)values('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;
Run Code Online (Sandbox Code Playgroud)
这就是AutoCommit属性在Zeos中的实际工作方式:
当AutoCommit为True时,则在每个执行的SQL语句之后自动提交事务,但是您可以明确地使用StartTransaction命令来阻止此自动提交,直到您明确地调用Commit.
当AutoCommit为False时,您不应该调用StartTransaction.然后事务自动启动,但在每个执行的语句后都不会自动提交.
procedure StartTransaction StartTransaction过程在连接的数据库中启动新事务.它应该仅在AutoCommit属性为TRUE时使用.每当您尝试使用AutoCommit设置为false调用它时,将引发SInvalidOpInNonAutoCommit.此行为是预期的,因为StartTransaction应该用作AutoCommit模式的转义.当您调用StartTransaction时,AutoCommit将"关闭",然后,当您调用Commit或Rollback时,AutoCommit将再次"打开".如果您使用AutoCommit设置为false,则会自动创建新事务,并选择关闭它们的方式(Commit或Rollback).
procedure Commit将当前语句提交到数据库.应仅在非AutoCommit模式下使用(其中每个语句都是自动提交的,使此过程无效),或者当您处于AutoCommit模式并希望完成StartTransaction过程打开的事务时.提交完成当前事务,如果有的话.如果您不想将satatements保存到数据库,则应使用Rollback过程.
procedure Rollback回滚当前事务中的所有先前语句.应仅在非AutoCommit模式下使用(其中每个语句都是自动提交的,使此过程无效),或者当您处于AutoCommit模式并希望完成StartTransaction过程打开的事务时.Rollback完成当前事务,如果有的话.如果您不想丢失您的声明,则应使用Commit过程.
我不知道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;
Run Code Online (Sandbox Code Playgroud)
查询现在运行得更快(因为DBMS可以编译一次并重复使用多次(我提到的"缓存"),您不再具有SQL注入风险,并且不再需要多个语句.
尝试此代码,如果出现同样的问题,请告诉我们:
with ZQuery1 do
begin
SQL.Clear;
SQL.Add('insert into client (name,age) values ('+QuotedStr('john')+','+QuotedStr('20')+'),('+QuotedStr('doe')+','+QuotedStr('21')+');');
ExecSQL;
end;
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您还可以加快 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;
Run Code Online (Sandbox Code Playgroud)
编辑#2:交易
Stackoverflow 上的一个问题有很多关于在 MySQL 中使用事务的好例子。虽然这些示例是为 PHP 编写的,但我相信您可以在那里找到一些很好的指导。确保 MySQL 服务器上的表InnoDB不是MyISAM.
| 归档时间: |
|
| 查看次数: |
7654 次 |
| 最近记录: |