Логин: Пароль:    Регистрация Всеми возможностями сайта можно пользоваться
только после авторизации.
   Забыли пароль?

Поиск
L



Статистика
u
Пользователи онлайн: нет
Гостей онлайн: 1
Всего онлайн: 1
Зарегистрировано юзеров: 6943
Комментариев на сайте: 654
Новый юзер: MatthewMat



Последние комментарии
c
Davidpab прокомментировал "Урок 24 - Изучаем компонент PaintBox":
&#1047;&#1072;&#1082;&#1072;&#1079;&#1072;&#1090;&#1100; seo &#1087;&#1086;&#1080;&#1089;&#1082;&#1086;&#1074;&#1091;&#1102; &#1086;&#1087;&#1090;&#1080;&#1084;&#1080;&#1079;&#1072;&#1094;&#1080;&#1102; &#1089;&#1072;&#1081;&#1090;&#1072;, <a href=http://seoprofisional.ru/bazy>базы для xrumer</a> &#1047;&#1072;&#1082;&#1072;&#1079;&#1072;&#1090;&#1100; &#1091;&#1089;&#1083;&#1091;&#1075;&#1080; &#1087;&#1086; &#1087;&#1088;&#1086;&#1076;&#1074;&#1080;&#1078;&#1077;&#1085;&#1080;&#1102; &#1089;&#1072;&#1081;&#1090;&#1072; &#1055;&#1086; &#1074;&#1089;&#1077;&#1084; &#1074;&#1086;&#1079;&#1085;&#1080;&#1082;&#1096;&#1080;&#1084; &#1074;&#1086;&#1087;&#1088;&#1086;&#1089;&#1072;&#1084; &#1042;&#1099; &#1084;&#1086;&#1078;&#1077;&#1090;&#1077; &#1086;&#1073;&#1088;&#1072;&#1090;&#1080;&#1090;&#1100;&#1089;&#1103; &#1074; &#1089;&#1082;&#1072;&#1081;&#1087; &#1083;&#1086;&#1075;&#1080;&#1085; [b]pokras7777[/b] &#1056;&#1072;&#1089;&#1082;&#1088;&#1091;&#1090;&#1082;&#1072; &#1089;&#1072;&#1081;&#1090;&#1072; &#1087;&#1086;&#1076; &#1082;&#1083;&#1102;&#1095; fhdxxxxxd
Everettrof прокомментировал "Урок 53 - Потоки в Delphi, (часть 1/3)":
Как быть не могу разобраться или тут хочу заказать металлоизделия Делается тут или в другом месте искать навесы из полекарбоната Такие фирмы это делают или я не правильно понимаю, нужно сделать а я вот выбираю и не могу понять,,, сварка металла это же они могут сделать??? https://steelcentury.ru пока на них смотрю

Создание генераторов и триггеров в InterBase

В данной статье я опишу реализацию небольшой утилиты для InterBase, которая создает генераторы, автоматически вызываемые из триггеров. На создание такой утилиты меня подвигло то, что я не нашел никакого средства для этого, а создавать генераторы руками мне неудобно, да и слишком много времени это отнимает.

Общая информация
Вообще, считается хорошим стилем создание первичного ключа в виде уникального числа. Мало того, это наиболее удобный способ для связи таблиц. Такой первичный ключ часто называют "айдишкой" (от слова "ID", идентификатор) таблицы.

Значения такого поля могут задаваться и вручную, но тогда придется вручную же контролировать их уникальность, что практически невозможно при многопользовательском режиме использования БД. Для этого в InterBase был включен механизм "генераторов", аналогичный механизму "последовательностей" в Oracle. Единственная цель генератора - дать уникальное (в его контексте) числовое значение при вызове.

Сами по себе генераторы практически не имеют смысла, так как они никак не связаны с таблицами БД. Для запроса значения генератора применяются триггеры, автоматически вызываемые СУБД при возникновении определенных событий. В основном, триггер, использующий генератор, вызывается по событию "BeforeInsert", то есть перед непосредственной вставкой данных.

Текст создания классического генератора и триггера для него, в общем случае, выглядит следующим образом:

CREATE GENERATOR GEN_%TBL_NAME%;
CREATE TRIGGER NEW_%TBL_NAME% FOR %TBL_NAME%
ACTIVE BEFORE INSERT POSITION 0
AS
begin
  if (NEW.%ID_FIELD% is NULL) then NEW.%ID_FIELD% = gen_id(GEN_%TBL_NAME%,1);
end
Здесь %TBL_NAME% - имя таблицы, для которой создается триггер и генератор, а %ID_FIELD% - имя поля, являющегося первичным ключом.

Реализация
Итак, для реализации утилиты нам необходимо для начала найти список таблиц базы данных, а также их первичных ключей. Для этого мы сделаем запросы к словарю данных базы (словарь данных еще называется метаданными), который содержится в системных таблицах, имена которых начинаются с последовательности "rdb$".

Список таблиц можно получить следующим образом:
select rdb$relation_name from rdb$relations
where (rdb$system_flag=0) and (rdb$view_source is null)
order by rdb$relation_name asc;
Список первичных ключей получаем так:
select i.rdb$field_name from rdb$relation_constraints r, rdb$index_segments i
where r.rdb$relation_name=:TBL_NAME and r.rdb$constraint_type='PRIMARY KEY'
and r.rdb$index_name=i.rdb$index_name order by i.rdb$field_position
Теперь все необходимое для дальнейшей работы получено и мы можем создавать генераторы с триггерами.

Предположив, что вы уже создали модуль данных и окно подключения к базе данных, перейду сразу к содержательной части. Предлагаю вам создать вот такое окно:

В поле списка опций (большое белое поле) у нас будут имена таблиц, а надписи на кнопках говорят сами за себя. Как вы видите, ничего сложного. Код обработки нажатия на кнопку "Create generators..." таков:
procedure TForm2.btnCreateClick(Sender: TObject);
var i: integer;
begin
  with dm do for i := 0 to pred(lbTables.Count) do
  begin
    if lbTables.Checked[i] then
      if not HasTrigger(lbTables.Items[i]) then
      begin
        if not tm.InTransaction then tm.StartTransaction;
        try CreateTriggeredGenerator(lbTables.Items[i]);
        except
          tm.Rollback;
          showmessage('Unable to create objects for the table '+lbTables.Items[i]+'.');
        end;
        if tm.InTransaction then
        begin
          tm.Commit;
          showmessage('Objects for the table '+lbTables.Items[i]+' is successfully created.');
        end;
      end;
  end;
end;
Здесь для каждой выбранной в списке таблицы проверяется, существует ли уже триггер с генератором для этой таблицы. Если нет, то они создаются.

Проверка существования триггера выглядит вот таким образом:
function TForm2.HasTrigger(const TableName: string): boolean;
var s: string;
    i: integer;
begin
  Result := false;
  if (Gens.Count < 1) then exit;
  with dm do
  begin
    qHasTrigger.ParamByName('TBL_NAME').Value := TableName;
    qHasTrigger.Open;
    while not qHasTrigger.Eof do
    begin
      s := qHasTrigger.FieldByName('rdb$trigger_source').AsString;
      if (length(s) > 0) then
        for i := 0 to pred(Gens.Count) do
          if pos(UpperCase(Gens[i]),UpperCase(s)) > 0 then Result := true;
      qHasTrigger.Next;
    end;
    qHasTrigger.Close;
  end;
end;


Вот и всё, Удачи!

Источник: www.thedelphi.ru
Автор: Савельев Александр
Опубликовано: 14 Июня 2015
Просмотров:


Зарегистрируйтесь или авторизуйтесь, чтобы добавлять комментарии.