Delphi: как создать базу данных Firebird программно - PullRequest
3 голосов
/ 05 мая 2010

Я использую 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;

Файл SQL из IBExpert:

/******************************************************************************/
/*                 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 Ответ

2 голосов
/ 05 мая 2010

Как правило, вы можете создавать объекты базы данных Firebird в любом порядке, при условии, что они не зависят друг от друга. Если это так, то, очевидно, вам нужно создать зависимые объекты перед созданием зависимых объектов.

Если у вас есть объекты с круговыми ссылками, то сначала создайте один из них с пустым телом, создайте другой, а затем заполните содержимое первого, используя ALTER TABLE или соответствующий оператор. Такие инструменты, как IBExpert, Database Workbench или FlameRobin анализируют зависимости, поэтому следование порядку создания в написанных ими скриптах всегда должно работать.

Если ваш сценарий, созданный IBExpert, работает, но ваш собственный код, выполняющий действия в том же порядке, не работает, то причина этого может заключаться в том, что IBExpert фиксирует каждый оператор DDL отдельно (тогда как ваш код «т). Вы можете сделать то же самое в своем коде, и вы должны. Ваш столбец autoinc включает триггер, который сам зависит от генератора, поэтому убедитесь, что вы зафиксировали после создания таблицы и генератора, прежде чем создавать триггер.

Edit:

Вам следует убедиться, что вы выполняете только несколько операторов с компонентами базы данных, которые могут это сделать. Я не знаю Zeos, но из этой статьи базы знаний кажется, что и 1016 *, и TZUpdateSQL поддерживают несколько операторов в одном вызове выполнения. В качестве альтернативы вы можете использовать TZSQLProcessor для загрузки полного сценария, созданного IBExpert, и его выполнения.

Метод TZConnection.ExecuteDirect(), с другой стороны, может не поддерживать несколько операторов, и в этом случае вы получите синтаксические ошибки после окончания первого оператора. Это

CREATE GENERATOR GEN_EMAIL_ACCOUNTS_ID;
SET GENERATOR GEN_EMAIL_ACCOUNTS_ID TO 2;

- это два утверждения, и вам может потребоваться передать каждое отдельно TZConnection.ExecuteDirect().

...