Обновление MIS3

Материал из ИбисоПедии
Версия от 08:44, 26 августа 2019; Admin (обсуждение | вклад) (Разрабатываемая система (Нефедов))
Перейти к: навигация, поиск

Обновление метаданных

При создании скриптов обновляющих объекты БД можно использовать проверку на существование обновляемых объектов БД. Для этого достаточно написать небольшой блок кода.

Схема

Пример кода проверяющий схему

DO
$$
BEGIN
   IF NOT EXISTS(  select schema_name
                   from information_schema.schemata
                   where schema_name = 'etl') -- вместо etl указать имя схемы
   THEN
   --    <<Далее скрипт что-то делающий>>
   END IF ;
END;
$$

Таблица

Пример кода, проверяющий наличие таблицы в БД и при её отсутствии создающий её:

DO
$$
BEGIN
   IF NOT EXISTS(SELECT *
                    FROM information_schema.tables where table_schema||'.'||table_name='audit.logged_actions')
                    -- Вместо 'audit.logged_actions' необходимо указать имя схемы БД в которой располагается объект
                    -- и через точку указать имя проверяемой таблицы
                    THEN
       <<Далее скрипт создающий таблицу в БД. Например: CREATE TABLE audit.logged_actions... >>
   END IF ;
END;
$$

Триггер

Пример кода, проверяющий наличие в БД триггера и при его отсутствии создающий его:

DO
$$
BEGIN
   IF NOT EXISTS(SELECT *
                    FROM information_schema.triggers
                    WHERE event_object_table = 'warehouse_accounting_entry' -- вместо warehouse_accounting_entry необходимо указать имя таблицы за которой закреплён триггер
                    AND trigger_name = 'audit_trigger_row' ) -- вместо audit_trigger_row указать имя тригера
                    THEN
       <<Далее скрипт создающий таблицу в БД. Например: CREATE TRIGGER audit_trigger_stm...>>
   END IF ;
END;
$$

Поле

Пример кода, проверяющий наличие поля БД и при его отсутствии создающий его (mm.table-имя таблицы, куда добавляется поле, newcolumn-название нового поля, comment-описание поля):

DO
$$
BEGIN
  IF NOT EXISTS(SELECT *
                FROM information_schema.columns where table_schema||'.'||table_name||'.'||column_name='mm.table.newcolumn')
  THEN
     <<Далее скрипт создающий поле в таблице, например:>>
     ALTER TABLE mm.table ADD COLUMN newcolumn BOOLEAN;
     ALTER TABLE mm.table ALTER COLUMN newcolumn SET DEFAULT false;
     COMMENT ON COLUMN mm.table.newcolumn IS 'comment';
  END IF;
END;
$$


Индекс

Пример кода, проверяющий наличие в БД индекса и при его отсутствии создающий его:

 DO
 $$
 BEGIN
 -- Внимание! заменить в трех местах и DDL
  IF  EXISTS(SELECT *
               FROM information_schema.tables 
              WHERE table_schema||'.'||table_name='pump.tarimu') -- заменить здесь 1 !!!!
  THEN
    -- если таблица существует                   
  
    if not exists (
       select t.relname as "table_name",
              i.relname as indname
       FROM pg_index as idx
            JOIN pg_class as i ON i.oid = idx.indexrelid
            JOIN pg_am as am ON i.relam = am.oid
            JOIN pg_namespace as ns ON ns.oid = i.relnamespace AND ns.nspname =
              'pump'  -- заменить здесь 2 !!!!
            join pg_class t on idx.indrelid = t.oid
       where idx.indexprs is null -- исключаем функциональные индексы
             and
             i.relname = 'ix_tarimu$code' -- -- заменить здесь 3 !!!!
             ) 
    then  
    ------------- DDL ---------------------
          CREATE INDEX ix_tarimu$code ON pump.tarimu
             USING btree (code COLLATE pg_catalog."default");
    end if; 
   -----------------------------------------
  END IF ;  
 END;
 $$

FOREGN KEY

 DO
 $$
 DECLARE
   v_schema varchar;
   v_table varchar;
   v_contraint_name varchar;
 BEGIN
   v_schema := 'an';
   v_table := 'ds_sql_smart_field';
   v_contraint_name := 'fk_ds_sql_smart_field$ds_sql_smart$ds_sql_smart_id';
 
  IF NOT EXISTS(      SELECT tc.constraint_name,
          tc.table_schema,
          tc.table_name,
          kcu.column_name,
          ccu.table_name AS foreign_table_name,
          ccu.column_name AS foreign_column_name
   FROM information_schema.table_constraints AS tc
        JOIN information_schema.key_column_usage AS kcu ON tc.constraint_name =
          kcu.constraint_name
        JOIN information_schema.constraint_column_usage AS ccu ON
          ccu.constraint_name = tc.constraint_name
   WHERE constraint_type = 'FOREIGN KEY' and
         tc.table_schema = v_schema and
         tc.table_name = v_table
         and tc.constraint_name=v_contraint_name ) -- вместо etl указать имя схемы
  THEN
  --    <<Далее скрипт добавляющий>>
 ALTER TABLE an.ds_sql_smart_field
 ADD CONSTRAINT fk_ds_sql_smart_field$ds_sql_smart$ds_sql_smart_id FOREIGN KEY (ds_sql_smart_id)
   REFERENCES an.ds_sql_smart(id)
   ON DELETE RESTRICT
   ON UPDATE RESTRICT
   NOT DEFERRABLE;
  
  ELSE
    -- TODO проверить на переименование 
  END IF ;
 END;
 $$

Добавление параметров в MM.ADJ для скриптов обновления БД

Пример кода, проверяющий наличие параметра в mm.adj и при его отсутствии создающий его (SEC_NAME-имя секции, PARAM_NAME-название параметра, comment-описание параметра):

DO
$$
BEGIN
IF NOT EXISTS (SELECT id from mm.adj where section='SEC_NAME' and "key"='PARAM_NAME' )
THEN
  INSERT INTO mm.adj ("section", "key", "value", "note")
  VALUES ('SEC_NAME', 'PARAM_NAME', '0', 'comment');
END IF;
END;
$$


Данные в таблицах, которые должны быть одинаковыми на всех БД

  • mm.app_tab - справочник закладок
  • mm.rght - только первые 1000 записей, остальные все одинаковые
  • mm.rsf_ref_column - колонки по реестру счетом
  • audit.table_conf - назначение мест аудита для таблиц

Проблема транзакции в регистратуре

Следующие таблицы находятся в эксклюзивной блокировке:

  • ambticket
  • ambdoc
  • company_insur
  • idoc
  • idoc_tepe
  • pay_type
  • naz
  • naz_dict
  • mdoc
  • mdoc_type
  • people
  • pinfo
  • place_mdoc
  • xpass
  • sex
  • type_programm

Любые изменения структуры (в том числе триггеры) будут висеть. Также будут висеть при измении таблиц, связанных constraint.