Delphi:如何以编程方式创建Firebird数据库

时间:2010-05-04 21:12:28

标签: database delphi firebird firebird2.1 zeos

我正在使用D2K9,Zeos 7Alpha和Firebird 2.1

在添加autoinc字段之前,我已经完成了这项工作。虽然我不确定我是100%正确地做到了。我不知道用什么命令来做SQL代码,有触发器,生成器等等。我已经尝试了几种组合,我猜我做错了,只是因为这不起作用。

当前演示:   http://uploading.com/files/bd64d8m9/createdb.zip/

当前错误:

It's getting an error here:

SQL Error:  Dynamic SQL Error SQL error code = -104 Token unknown - line 2, column 1 SET.
Error Code: -104. Invalid token The SQL:
 CREATE GENERATOR GEN_EMAIL_ACCOUNTS_ID;

SET GENERATOR GEN_EMAIL_ACCOUNTS_ID TO 1;

来自IBExpert的SQL文件:

/******************************************************************************/
/*                 Generated by IBExpert 5/4/2010 3:59:48 PM                  */
/******************************************************************************/

/******************************************************************************/
/*        Following SET SQL DIALECT is just for the Database Comparer         */
/******************************************************************************/
SET SQL DIALECT 3;



/******************************************************************************/
/*                                   Tables                                   */
/******************************************************************************/


CREATE GENERATOR GEN_EMAIL_ACCOUNTS_ID;

CREATE TABLE EMAIL_ACCOUNTS (
    ID           INTEGER NOT NULL,
    FNAME        VARCHAR(35),
    LNAME        VARCHAR(35),
    ADDRESS      VARCHAR(100),
    CITY         VARCHAR(35),
    STATE        VARCHAR(35),
    ZIPCODE      VARCHAR(20),
    BDAY         DATE,
    PHONE        VARCHAR(20),
    UNAME        VARCHAR(255),
    PASS         VARCHAR(20),
    EMAIL        VARCHAR(255),
    CREATEDDATE  DATE,
    "ACTIVE"     BOOLEAN DEFAULT 0 NOT NULL /* BOOLEAN = SMALLINT CHECK (value is null or value in (0, 1)) */,
    BANNED       BOOLEAN DEFAULT 0 NOT NULL /* BOOLEAN = SMALLINT CHECK (value is null or value in (0, 1)) */,
    "PUBLIC"     BOOLEAN DEFAULT 0 NOT NULL /* BOOLEAN = SMALLINT CHECK (value is null or value in (0, 1)) */,
    NOTES        BLOB SUB_TYPE 0 SEGMENT SIZE 1024
);




/******************************************************************************/
/*                                Primary Keys                                */
/******************************************************************************/

ALTER TABLE EMAIL_ACCOUNTS ADD PRIMARY KEY (ID);


/******************************************************************************/
/*                                  Triggers                                  */
/******************************************************************************/


SET TERM ^ ;



/******************************************************************************/
/*                            Triggers for tables                             */
/******************************************************************************/



/* Trigger: EMAIL_ACCOUNTS_BI */
CREATE OR ALTER TRIGGER EMAIL_ACCOUNTS_BI FOR EMAIL_ACCOUNTS
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
  IF (NEW.ID IS NULL) THEN
    NEW.ID = GEN_ID(GEN_EMAIL_ACCOUNTS_ID,1);
END
^


SET TERM ; ^



/******************************************************************************/
/*                                 Privileges                                 */
/******************************************************************************/

触发器:

/******************************************************************************/
/*        Following SET SQL DIALECT is just for the Database Comparer         */
/******************************************************************************/
SET SQL DIALECT 3;

CREATE GENERATOR GEN_EMAIL_ACCOUNTS_ID;

SET TERM ^ ;



CREATE OR ALTER TRIGGER EMAIL_ACCOUNTS_BI FOR EMAIL_ACCOUNTS
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
  IF (NEW.ID IS NULL) THEN
    NEW.ID = GEN_ID(GEN_EMAIL_ACCOUNTS_ID,1);
END
^


SET TERM ; ^

发生器:

CREATE SEQUENCE GEN_EMAIL_ACCOUNTS_ID;
ALTER SEQUENCE GEN_EMAIL_ACCOUNTS_ID RESTART WITH 2;

/* Old syntax is:
CREATE GENERATOR GEN_EMAIL_ACCOUNTS_ID;
SET GENERATOR GEN_EMAIL_ACCOUNTS_ID TO 2;
*/

我的代码:以下评论中的演示。

1 个答案:

答案 0 :(得分:2)

通常,您可以按任何顺序创建Firebird数据库对象,前提是它们不相互依赖。如果他们这样做,那么显然你需要在创建依赖对象之前创建依赖对象。

如果您有包含循环引用的对象,则首先使用空主体创建其中一个,创建另一个,然后使用ALTER TABLE或相应的语句填写第一个内容。像IBExpert,Database Workbench或FlameRobin这样的工具可以分析依赖关系,因此遵循它们编写的脚本中的创建顺序应始终有效。

如果您的IBExpert创建的脚本有效,但您自己的代码以相同的顺序执行操作不起作用,那么原因可能在于IBExpert分别提交每个DDL语句(而您的代码不是)。你可以在你的代码中做同样的事情,你应该这样做。你的autoinc列涉及一个触发器,它本身依赖于一个生成器,因此在创建触发器之前,请确保在创建表和生成器之后提交。

修改

您应该确保只使用能够执行此操作的数据库组件执行多个语句。我不知道Zeos,但是从this knowledge base article来看,似乎TZQueryTZUpdateSQL都支持一次执行调用中的多个语句。或者,您应该能够使用TZSQLProcessor加载由IBExpert创建的完整脚本并执行它。

另一方面,方法TZConnection.ExecuteDirect()可能不支持多个语句,在这种情况下,您将在第一个语句结束后收到语法错误。此

CREATE GENERATOR GEN_EMAIL_ACCOUNTS_ID;
SET GENERATOR GEN_EMAIL_ACCOUNTS_ID TO 2;

是两个陈述,您可能需要将每个陈述单独传递给TZConnection.ExecuteDirect()