Delphi - Creating MySQL database at runtime

╄→尐↘猪︶ㄣ 提交于 2019-12-23 13:09:17

问题


I have a delphi application which connects to MySQL database, however, I would like to give create an easy way for my end user to implement the MySQL database. I thought about creating a button within my application which the user could press to delete any current instances of the scehma, and create a new schema with the correct tables and columns which my application requires to function.

I have written the code to create the new database. It is as follows:

CREATE SCHEMA IF NOT EXISTS fakeschema;   
USE fakeschema;  
CREATE TABLE table1  
(IDtable1 int(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,  
Line1 varchar(45),  
Line2 varchar(45));  

The code functions correctly within MySQL, however I am receiving an SQL Syntax error when executing the code. I am getting of:

error in your SQL syntax near 'USE fakeschema; CREATE TABLE table1 (IDtable1 int(11) PRIMARY KEY NO'

I am using an ADOConnection to link to the datasource. I am writing the connection string once the button has been pressed. I am using an ADOQuery to execute the SQL code.

Here is a snippet of the code which I am using to connect to the database:

ADOC.ConnectionString := 'PROVIDER = MSDASQL; DRIVER={MySQL ODBC 3.51 Driver};
SERVER=localhost; Data Source=faketest; DATABASE=fakeschema; USER ID=root;
PASSWORD=pass; OPTION=3;';
ADOC.DefaultDatabase := 'fakeschema';  
ADOC.Connected := True;  

Am I using the wrong tools/methods? I am new to MySQL and I am currently learning Delphi.


回答1:


As mentioned in one of my comments, the issue is trying to execute multiple individual SQL statements in a single TAdoQuery component.

In an ideal world, you would have a component such as MyDAC which has a script component you could use in place of the TAdoQuery (MyDAC would give you other benefits too such as not having to connect via ODBC). I don't know if there any free MySQL components out there which have a scripting component.

Another approach is you could create a script file (eg createFakeSchema.sql) and execute it through the command line. eg:

createFakeSchema.sql:

CREATE SCHEMA IF NOT EXISTS fakeschema;   
USE fakeschema;  
CREATE TABLE table1  
(IDtable1 int(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,  
Line1 varchar(45),  
Line2 varchar(45));

and example source code:

procedure TfrmMain.DoExecuteScriptFile;
var
  cmd: string;
  KeepOpen: Boolean;
begin
  KeepOpen := True;

  // option to automatically close window once execution is done
  // for releasing you would not want it kept open, but handy for debugging
  if KeepOpen then
    cmd := '/k '
  else
    cmd := '/c ';

  cmd := cmd + Format(' mysql -uroot -proot -D%s < "%s"', ['FakeSchema', 'createFakeSchema.sql']);
  ShellExecute(handle,'open', 'cmd.exe', Pchar(cmd), nil, SW_SHOW );
end;

This way you can create your script file externally somewhere, test it through MySQL yourself then when you know your script is working, you can run it through your program. If you want to hide the command window while executing change the SW_SHOW in ShellExecute to SW_HIDE. This way you don't even need any components at all - just have mysql.exe accessible in the path or include the full path in the cmd statement.

This was done in MySQL 5.1, so hopefully works for 3.5...




回答2:


If you look at the documentation for MySQL 3.x, and scroll waaay down the page on CREATE TABLE, you'll see an example in one of the comment posts of what appears to be the proper syntax. It appears to be more like this (untested, of course):

CREATE TABLE IF NOT EXISTS Table1 (
  IDtable1 int(11) NOT NULL AUTO_INCREMENT,  
  Line1 varchar(45),  
  Line2 varchar(45)
  PRIMARY KEY (IDTable1)
);

Here's another example I found at DevArticles

CREATE TABLE `articles` (
  `aID` int(4) NOT NULL auto_increment,
  `auth` varchar(100) NOT NULL default '',
  `title` varchar(100) NOT NULL default '',
  `article_body` text NOT NULL,
  `date_published` date NOT NULL default '0000-00-00',
  PRIMARY KEY  (`aID`)
) 

You might want to reconsider your strategy, though. If the user accidentally clicks the Reset Database button and deletes all of their data, this may cause you some issues (possibly legal ones, depending on where you live and what data is involved). :-)

It might be better to think of backing up the data and then do a TRUNCATE of the tables instead, where you could restore from the backup if something went wrong. This would allow re-use of the existing schema.




回答3:


If you ever receive a MySQL error message like

error in your SQL syntax near '(quoted)'

you always have to look at the code that is before that quoted part.

In this special case CREATE SCHEMA IF NOT EXISTS fakeschema;

The documentation is also very clear about that

CREATE SCHEMA is a synonym for CREATE DATABASE as of MySQL 5.0.2.

So you cannot use this synonym, because your MySQL server (version below 5.0.2) or in this case the ODBC driver did not know this.

This should get rid of the current error message

CREATE DATABASE IF NOT EXISTS fakeschema;   
USE fakeschema;  
CREATE TABLE table1(
  IDtable1 int(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,  
  Line1    varchar(45),  
  Line2    varchar(45)
);  



回答4:


A solution (based on @Jason 's) that does not involves cmd.exe is to use mysql source command:

cmd := '-u USER_NAME -pUSER_PASSWORD DB_NAME -e "source createFakeSchema.sql"';
ShellExecute(handle, 'open', 'mysql.exe', Pchar(cmd), 'PATH_TO_MYSQL', SW_SHOW);



回答5:


I did a hard job to find how to create a database. I'm using "Zeos":

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ShellAPI, ZAbstractConnection, ZConnection, DB,
  ZAbstractRODataset, ZAbstractDataset, ZDataset;

type
  TForm1 = class(TForm)
    btn1: TButton;
    ZConnection1: TZConnection;
    ZQuery: TZQuery;
    btn2: TButton;
    procedure btn1Click(Sender: TObject);
    procedure btn2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btn1Click(Sender: TObject);
begin
  ZConnection1.Protocol := 'mysql-5';
  ZConnection1.Database := '';
  ZConnection1.User := 'root';
  ZConnection1.Password := 'root';
  ZConnection1.Connect;
end;

procedure TForm1.btn2Click(Sender: TObject);
var
  vSQL : string;
begin
  ZQuery.Close;
  ZQuery.SQL.Clear;
  vSQL := 'CREATE DATABASE IF NOT EXISTS `test`';
  ZQuery.SQL.Add(vSQL);
  ZQuery.ExecSQL;
end;

end.

I hope that I can help anyone;

Best Regards



来源:https://stackoverflow.com/questions/16048092/delphi-creating-mysql-database-at-runtime

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