Delphi - 在运行时创建MySQL数据库

4
我有一个Delphi应用程序连接到MySQL数据库,但是,我想为我的最终用户创建一种简单的方式来实现MySQL数据库。我考虑在自己的应用程序中创建一个按钮,让用户可以按下该按钮来删除任何当前存在的模式,并创建一个具有正确表和列的新模式,这些表和列是我的应用程序需要执行的。
我已经编写了创建新数据库的代码,如下所示:
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));  

MySQL中的代码功能正常,但在执行代码时收到了SQL语法错误。我正在获得以下内容:
"error in your SQL syntax near 'USE fakeschema; CREATE TABLE table1 (IDtable1 int(11) PRIMARY KEY NO'"
我使用ADOConnection链接到数据源。一旦按钮被按下,我就会编写连接字符串。我使用ADOQuery来执行SQL代码。
以下是我用于连接到数据库的代码片段:
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;  

我是否在使用错误的工具/方法?我是MySQL的新手,目前正在学习Delphi。


我收到了一个SQL语法错误,但不提供具体的错误信息是没有意义的。请[编辑]您的问题并包含确切的错误消息。谢谢。 - Ken White
@KenWhite,我已经进行了编辑。谢谢。 - Turtle254
@KenWhite 我明白你的意思。我以前也遇到过很多麻烦,但只需要编辑几个字符就可以解决。然而,在这里似乎不是这种情况。我尝试删除auto_inc和notnull,并尝试从“line1”部分开始列括号,以便完全删除id行...但没有成功。两者都提供了完全相同的错误,只是显示相应的代码行。 - Turtle254
你需要使用与 TAdoQuery 不同的组件吗?它可能仅需执行单个语句。我知道,在 Interbase/Firebird 样式中,您需要使用 TIBScript 组件来“一次性”执行多个语句。但我不确定,这只是一个猜测。 - Jason
请忽略我上一条评论。文档对于这里所需的内容并不是很清楚。我还在继续查找。 :-) - Ken White
显示剩余4条评论
5个回答

4

正如我在评论中提到的,问题在于尝试在单个TAdoQuery组件中执行多个单独的SQL语句。

在理想情况下,您将拥有像MyDAC这样的组件,其中包含一个脚本组件,可用于代替TAdoQuery(MyDAC还会为您带来其他好处,例如无需通过ODBC连接)。 我不知道是否有免费的MySQL组件具有脚本组件。

另一种方法是创建一个脚本文件(例如createFakeSchema.sql),并通过命令行执行它。 例如:

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));

下面是示例源代码:

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;

这样你就可以在外部创建脚本文件,通过MySQL进行测试,当你确认你的脚本正常工作后,就可以通过程序运行它。如果你想要在执行过程中隐藏命令窗口,可以将ShellExecute中的SW_SHOW更改为SW_HIDE。这样你甚至不需要任何组件——只需将mysql.exe置于路径中或在cmd语句中包含完整路径即可。
这是在MySQL 5.1中完成的,希望对3.5也适用...

谢谢你的帮助。我已经将查询拆分并创建了一个单独的查询来创建数据库。我有一个简单地创建数据库“fakeschema”,然后我有一个单独的“ADOQuery”,它添加SQL到“CREATE table1”,执行SQL,清除查询,然后添加和执行下一个表的SQL等。它工作得很好。我喜欢从文件中执行的想法,并可能在以后使用它。 - Turtle254

0

如果您查看MySQL 3.x的文档,并在CREATE TABLE页面上向下滚动,您会在其中一个评论帖子中看到一个示例,该示例似乎是正确语法的样子。它看起来更像这样(当然未经测试):

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

这是我在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`)
) 

不过,您可能需要重新考虑您的策略。如果用户意外点击了“重置数据库”按钮并删除了所有数据,这可能会给您带来一些问题(取决于您所在的地区和涉及的数据,可能会引起法律问题)。:-)

最好考虑备份数据,然后对表进行TRUNCATE,如果出现问题,可以从备份中恢复。这将允许重用现有模式。


2
我认为他的Create Table语句不是问题所在 - 在5.1版本上对我很好用 - 但在旧版本中可能存在差异。我认为问题在于尝试在单个TADOQuery组件中执行多个语句。 - Jason
@Jason:如果是这样的话,通过对TADOCommand组件进行快速更改可能会解决问题,因为我已经使用SQL Server执行了多个语句。正如我所说,我无法测试任何一种方式,因为我目前没有安装MySQL。MySQL 3.x的文档似乎表明语法是错误的,但我没有查看5.1,因为发帖人在连接字符串中提到了3.51(那时5.1的文档不相关)。:-) 对于TSQL,您必须省略GO(它仅由SSMS使用),但是发帖人的语法在数据类型更正方面运行良好。 - Ken White
完全有可能的。顺便说一句,我将TAdoCommand.CommandText设置为初始SQL(不包括创建数据库语句),并调用Execute后得到了和OP收到的完全相同的错误。从TAdoCommand.CommandText中删除"use fakeschema"这一行后,正常工作了,所以我还是倾向于在单个TAdoQuery中使用多个语句 :)。 - Jason
我的评论并不是关于“愚蠢”的问题。当你给他们一种可以意外执行的“删除所有内容”的方法时,这涉及到风险(对你和你的客户)。我知道有些公司因为客户使用了软件中设计用于重置数据的功能而被起诉,因为客户声称“文档没有写好”,导致他们损失了大量的财务数据。至于“用户创建表和数据库名称...并在查询中使用它们”,这是一个太大的问题,在评论中无法回答,但你可以将其发布为一个新问题。(我会更具体地回答。) - Ken White
@KenWhite 好的,我理解你的意思。感谢你的帮助。 - Turtle254
显示剩余2条评论

0

如果你收到了一个像这样的MySQL错误信息

error in your SQL syntax near '(quoted)'

你必须查看在这个引用部分之前的代码。

在这种特殊情况下,CREATE SCHEMA IF NOT EXISTS fakeschema;

文档也非常清楚地说明了这一点

CREATE SCHEMA是MySQL 5.0.2版本之后的CREATE DATABASE的同义词。

因此,你不能使用这个同义词,因为你的MySQL服务器(版本低于5.0.2)或者在这种情况下ODBC驱动程序不知道这个。

这应该可以摆脱当前的错误消息。

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)
);  

即使您删除了创建数据库语句,问题仍然存在,因为据我所知,OP试图在单个TAdoQuery中执行这三个语句。当然,正如您现在指出的那样,CREATE SCHEMA语句无法使用,但我相信他仍将遇到相同的问题(我在Delphi 7和MySQL 5.1上也是如此)。 - Jason

0
一个不涉及 cmd.exe 的解决方案(基于 @Jason 的)是使用 mysql source 命令:
cmd := '-u USER_NAME -pUSER_PASSWORD DB_NAME -e "source createFakeSchema.sql"';
ShellExecute(handle, 'open', 'mysql.exe', Pchar(cmd), 'PATH_TO_MYSQL', SW_SHOW);

0

我费了很大的力气才找到如何创建数据库。我正在使用"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.

希望我能帮助到任何人;

最好的祝福。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接