delphi dxExpress MySQL: invalid LAST_INSERT_ID value

不打扰是莪最后的温柔 提交于 2019-12-08 03:04:10

问题


I am developing an application in Delphi and want to insert records to Mysql's table. An then I want to know inserted record's identity value. So I write bellow code.
On run time , insert is done and record added but returned value for identity is zero!! what is my mistake ?!!

-- MySql  table create
CREATE TABLE Sample_Table (
  id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  mobile_number varchar(20) DEFAULT NULL,
  message_body text,
 PRIMARY KEY (id)
);

--- Delphi code

SQLCon := TSQLConnection.Create(self);
  with SQLCon do begin
   Close;
   DriverName := 'MySQL';
   GetDriverFunc := 'getSQLDriverMYSQL';
   LibraryName := 'dbxmys.dll';
   VendorLib := 'LIBMYSQL.dll';
   LoginPrompt := false;
   Params.Values['HostName'] := '127.0.0.1';
   Params.Values['Database'] := 'sms_test';
   Params.Values['User_Name'] := 'root';
   Params.Values['Password'] := 'root';
   Open;
end;

SQLQry := TSQLQuery.Create(self);
with SQLQry do begin
  Close;
  SQLConnection := SQLCon;

  SQL.Clear;
  SQL.Add('INSERT INTO Sample_Table ');
  SQL.Add('(mobile_number, message_body) VALUES');
  SQL.Add(format('(%s, %s);',[QuotedStr('989121011689'), QuotedStr('Text1')]));
  ExecSQL();
  Close;

  SQL.Clear;
  SQL.Add('SELECT LAST_INSERT_ID() EngineRefNo;');
  Open;
  First;
  ListBox1.items.Add(FieldByName('EngineRefNo').AsString);
  Close;
end;

SQLCon.Close;

any advise?


回答1:


You should get the ID in one go

SQLQry := TSQLQuery.Create(self);
with SQLQry do begin
  SQLConnection := SQLCon;

  SQL.Add('INSERT INTO Sample_Table ');
  SQL.Add('(mobile_number, message_body) VALUES');
  SQL.Add(format('(%s, %s);',[QuotedStr('989121011689'), QuotedStr('Text1')]));

  SQL.Add('SELECT LAST_INSERT_ID() EngineRefNo;');

  Open;
  ListBox1.items.Add(FieldByName('EngineRefNo').AsString);
  Close;
end;

SQLCon.Close;

and you should think about using parameters to prevent sql injection

SQLQry := TSQLQuery.Create(self);
with SQLQry do begin
  SQLConnection := SQLCon;

  SQL.Add('INSERT INTO Sample_Table ');
  SQL.Add('( mobile_number, message_body ) VALUES');
  SQL.Add('( :mobile_number, :message_body );');

  SQL.Add('SELECT LAST_INSERT_ID() EngineRefNo;');

  ParamByName( 'mobile_number' ).Value := '989121011689';
  ParamByName( 'message_body' ).Value := 'Text1';

  Open;
  ListBox1.items.Add(FieldByName('EngineRefNo').AsString);
  Close;
end;

SQLCon.Close;



回答2:


Apparently this is a problem known with delphi .

quoting the above link:

Certain ODBC applications (including Delphi and Access) may have trouble obtaining the auto-increment value using the previous examples. In this case, try the following statement as an alternative:

SELECT * FROM tbl WHERE auto IS NULL;

This alternative method requires that sql_auto_is_null variable is not set to 0. See Server System Variables

So in your case (untested):

SQLCon := TSQLConnection.Create(self);
  with SQLCon do begin
   Close;
   DriverName := 'MySQL';
   GetDriverFunc := 'getSQLDriverMYSQL';
   LibraryName := 'dbxmys.dll';
   VendorLib := 'LIBMYSQL.dll';
   LoginPrompt := false;
   Params.Values['HostName'] := '127.0.0.1';
   Params.Values['Database'] := 'sms_test';
   Params.Values['User_Name'] := 'root';
   Params.Values['Password'] := 'root';
   Open;
end;
SQLQry := TSQLQuery.Create(self);
with SQLQry do begin
  Close;
  SQLConnection := SQLCon;

  SQL.Clear;
  SQL.Add('INSERT INTO Sample_Table ');
  SQL.Add('(mobile_number, message_body) VALUES');
  SQL.Add(format('(%s, %s);',[QuotedStr('989121011689'), QuotedStr('Text1')]));
  ExecSQL();
  Close;

  SQL.Clear;
  SQL.Add('SELECT id FROM Sample_Table WHERE id IS NULL');
  Open;
  First;
  ListBox1.items.Add(FieldByName('Id').AsString);
  Close;
end;

SQLCon.Close;


来源:https://stackoverflow.com/questions/13729486/delphi-dxexpress-mysql-invalid-last-insert-id-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!