Модификация структуры базы данных
SYSDBA (обсуждение | вклад) (→Изменение версии структуры БД) |
SYSDBA (обсуждение | вклад) (→Создание процедуры модификации структуры существующей БД) |
||
| Строка 63: | Строка 63: | ||
=== Создание процедуры модификации структуры существующей БД === | === Создание процедуры модификации структуры существующей БД === | ||
| + | |||
| + | Теперь, после того, как мы создали файл со скриптом и добавили его в список create.bat, эталонная база будет формироваться уже с нашей таблицей. Но, как быть с теми базами. которые были созданы ранее и уже эксплуатируются у пользователей? Для внесения изменений в структуру существующей базы следует создать процедуру модификации. Обычно, каждая процедура находится в своем отдельном файле в подкаталоге Setup основного каталога проекта. Название юнита принято начинать с префикса mdf_. | ||
| + | |||
| + | unit mdf_AddTestTable; | ||
| + | |||
| + | interface | ||
| + | |||
| + | uses | ||
| + | IBDatabase, gdModify; | ||
| + | |||
| + | procedure AddTestTable(IBDB: TIBDatabase; Log: TModifyLog); | ||
| + | |||
| + | implementation | ||
| + | |||
| + | uses | ||
| + | IBSQL, SysUtils; | ||
| + | |||
| + | procedure AddTestTable(IBDB: TIBDatabase; Log: TModifyLog); | ||
| + | var | ||
| + | FTransaction: TIBTransaction; | ||
| + | FIBSQL: TIBSQL; | ||
| + | begin | ||
| + | Log('Начато добавление таблицы GD_TEST'); | ||
| + | FTransaction := TIBTransaction.Create(nil); | ||
| + | try | ||
| + | FTransaction.DefaultDatabase := IBDB; | ||
| + | FTransaction.StartTransaction; | ||
| + | try | ||
| + | FIBSQL := TIBSQL.Create(nil); | ||
| + | try | ||
| + | FIBSQL.Transaction := FTransaction; | ||
| + | |||
| + | FIBSQL.SQL.Text := | ||
| + | 'CREATE TABLE gd_test ( ' + #13#10 + | ||
| + | ' id dintkey, ' + #13#10 + | ||
| + | ' name dname ' + #13#10 + | ||
| + | ')'; | ||
| + | FIBSQL.ExecQuery; | ||
| + | |||
| + | FIBSQL.SQL.Text := | ||
| + | 'ALTER TABLE gd_test ADD CONSTRAINT gd_pk_test_id ' + #13#10 + | ||
| + | ' PRIMARY KEY (id)'; | ||
| + | FIBSQL.ExecQuery; | ||
| + | |||
| + | FIBSQL.SQL.Text := | ||
| + | 'CREATE TRIGGER gd_bi_test ' + #13#10 + | ||
| + | ' BEFORE INSERT ' + #13#10 + | ||
| + | ' POSITION 0 ' + #13#10 + | ||
| + | 'AS ' + #13#10 + | ||
| + | 'BEGIN ' + #13#10 + | ||
| + | ' IF (NEW.id IS NULL) THEN' + #13#10 + | ||
| + | ' NEW.id = GEN_ID(gd_g_unique, 1) + GEN_ID(gd_g_offset, 0); ' + #13#10 + | ||
| + | 'END'; | ||
| + | FIBSQL.ExecQuery; | ||
| + | |||
| + | FIBSQL.Close; | ||
| + | FIBSQL.SQL.Text := | ||
| + | 'INSERT INTO fin_versioninfo ' + | ||
| + | ' VALUES (100, ''0000.0001.0000.0127'', ''16.01.2008'', ''GD_TEST table added'')'; | ||
| + | try | ||
| + | FIBSQL.ExecQuery; | ||
| + | except | ||
| + | end; | ||
| + | |||
| + | FTransaction.Commit; | ||
| + | Log('Добавление таблицы GD_TEST успешно завершено'); | ||
| + | |||
| + | finally | ||
| + | FIBSQL.Free; | ||
| + | end; | ||
| + | except | ||
| + | on E: Exception do | ||
| + | begin | ||
| + | FTransaction.Rollback; | ||
| + | Log(E.Message); | ||
| + | end; | ||
| + | end; | ||
| + | finally | ||
| + | FTransaction.Free; | ||
| + | end; | ||
| + | end; | ||
| + | |||
| + | end. | ||
=== Добавление процедуры в общий список === | === Добавление процедуры в общий список === | ||
Версия 11:58, 24 августа 2008
Структура базы данных поставляемой с "голой" платформой называется эталонной, а сама база данных без пользовательских настроек – эталоном. Эталонная структура может меняться с выходом новых версий файла gedemin.exe. Для обновления существующих баз предусмотрен механизм модификации структуры. Рассмотрим его работу на следующем примере: пусть в эталонную структуру базы данных необходимо добавить таблицу GD_TEST и связанные с ней объекты: первичный ключ и триггер для его автоматического формирования.
Содержание |
Создание SQL скрипта
Первым делом создадим в подкаталоге SQL каталога GEDEMIN файл с именем gd_test.sql, который содержит следующий скрипт:
SET NAMES WIN1251;
SET SQL DIALECT 3;
CONNECT '<Имя сервера и путь к файлу с эталонной БД>'
USER 'SYSDBA' PASSWORD 'masterkey';
COMMIT;
CREATE TABLE gd_test (
id dintkey,
name dname
);
ALTER TABLE gd_test ADD CONSTRAINT gd_pk_test_id
PRIMARY KEY (id);
SET TERM ^ ;
CREATE TRIGGER gd_bi_test
BEFORE INSERT
POSITION 0
AS
BEGIN
IF (NEW.id IS NULL) THEN
NEW.id = GEN_ID(gd_g_unique, 1) + GEN_ID(gd_g_offset, 0);
END
^
SET TERM ; ^
COMMIT;
Изменение версии структуры БД
История изменения версии структуры БД хранится в таблице fin_versioninfo. Ее структура и наполнение задаются в файле gd_version.sql. Запись с максимальным идентификатором соответствует текущей версии структуры. Отыщем максимальный номер и добавим в указанный файл новую запись о версии:
INSERT INTO fin_versioninfo VALUES (100, '0000.0001.0000.0127', '16.01.2008', 'GD_TEST table added');
Обратите внимание, что в вашем случае идентификатор, строковое представление версии БД, дата внесения изменений будут другими!
Добавление вызова скрипта в пакетный файл формирования эталонной БД
Эталонная БД формируется с помощью пакетного файла create.bat из каталога SQL. Откроем его на редактирование и добавим строку вызова нашего скрипта:
... isql -i gd_file.sql rem Вызываем наш скрипт isql -i gd_test.sql makelbrbtree.exe /sn czech:k:\bases\gedemin\etalon.fdb /tmp tst_tree_tbl.sql ...
Как показано в примере выше, обычно, вызов новых скриптов добавляется в конец файла, перед вызовом утилиты переформирования интервальных деревьев.
Создание процедуры модификации структуры существующей БД
Теперь, после того, как мы создали файл со скриптом и добавили его в список create.bat, эталонная база будет формироваться уже с нашей таблицей. Но, как быть с теми базами. которые были созданы ранее и уже эксплуатируются у пользователей? Для внесения изменений в структуру существующей базы следует создать процедуру модификации. Обычно, каждая процедура находится в своем отдельном файле в подкаталоге Setup основного каталога проекта. Название юнита принято начинать с префикса mdf_.
unit mdf_AddTestTable;
interface
uses
IBDatabase, gdModify;
procedure AddTestTable(IBDB: TIBDatabase; Log: TModifyLog);
implementation
uses
IBSQL, SysUtils;
procedure AddTestTable(IBDB: TIBDatabase; Log: TModifyLog);
var
FTransaction: TIBTransaction;
FIBSQL: TIBSQL;
begin
Log('Начато добавление таблицы GD_TEST');
FTransaction := TIBTransaction.Create(nil);
try
FTransaction.DefaultDatabase := IBDB;
FTransaction.StartTransaction;
try
FIBSQL := TIBSQL.Create(nil);
try
FIBSQL.Transaction := FTransaction;
FIBSQL.SQL.Text :=
'CREATE TABLE gd_test ( ' + #13#10 +
' id dintkey, ' + #13#10 +
' name dname ' + #13#10 +
')';
FIBSQL.ExecQuery;
FIBSQL.SQL.Text :=
'ALTER TABLE gd_test ADD CONSTRAINT gd_pk_test_id ' + #13#10 +
' PRIMARY KEY (id)';
FIBSQL.ExecQuery;
FIBSQL.SQL.Text :=
'CREATE TRIGGER gd_bi_test ' + #13#10 +
' BEFORE INSERT ' + #13#10 +
' POSITION 0 ' + #13#10 +
'AS ' + #13#10 +
'BEGIN ' + #13#10 +
' IF (NEW.id IS NULL) THEN' + #13#10 +
' NEW.id = GEN_ID(gd_g_unique, 1) + GEN_ID(gd_g_offset, 0); ' + #13#10 +
'END';
FIBSQL.ExecQuery;
FIBSQL.Close;
FIBSQL.SQL.Text :=
'INSERT INTO fin_versioninfo ' +
' VALUES (100, 0000.0001.0000.0127, 16.01.2008, GD_TEST table added)';
try
FIBSQL.ExecQuery;
except
end;
FTransaction.Commit;
Log('Добавление таблицы GD_TEST успешно завершено');
finally
FIBSQL.Free;
end;
except
on E: Exception do
begin
FTransaction.Rollback;
Log(E.Message);
end;
end;
finally
FTransaction.Free;
end;
end;
end.