Изменения представления — различия между версиями

Материал из wiki.standart-n.ru
Перейти к: навигация, поиск
Строка 6: Строка 6:
 
  execute procedure PR_ALTER_VIEW('VW_WAREBASE','source','wb.mmbsh')
 
  execute procedure PR_ALTER_VIEW('VW_WAREBASE','source','wb.mmbsh')
  
 +
Установка:
 
<PRE>
 
<PRE>
 
SET TERM ^ ;
 
SET TERM ^ ;

Версия 13:28, 20 февраля 2016

Изменение VIEW

  • изменяет view - добавляет поля по 1 штуке

пока что без добавления join'ов - там всё не так однозначно

Пример:

execute procedure PR_ALTER_VIEW('VW_WAREBASE','source','wb.mmbsh')

Установка:

SET TERM ^ ;

create or alter procedure PR_ALTER_VIEW (
    VW_NAME DM_TEXT,
    NEW_VW_FIELD DM_TEXT,
    NEW_VW_VALUE DM_TEXT,
    NEW_VW_JOIN DM_TEXT = null)
as
declare variable I DM_ID;
declare variable VW_BODY DM_TEXT_BIG;
declare variable VW_FIELDS DM_TEXT_BIG;
declare variable J DM_ID;
declare variable STR DM_TEXT_BIG;
declare variable L integer;
begin
  if (:NEW_VW_JOIN is null) then
    NEW_VW_JOIN = '';
  select list(trim(RDB$FIELD_NAME))
  from (select RC.RDB$FIELD_NAME
        from RDB$RELATION_FIELDS RC
        where RC.RDB$RELATION_NAME = upper(:VW_NAME)
        order by RC.RDB$FIELD_POSITION)
  into :VW_FIELDS;
  select R.RDB$VIEW_SOURCE
  from RDB$RELATIONS R
  where R.RDB$RELATION_NAME = upper(:VW_NAME)
  into :VW_BODY;

  I = 0;
  J = 0;
  if ((select count(*)
       from RDB$RELATION_FIELDS RF
       where RF.RDB$RELATION_NAME = upper(:VW_NAME) and
             RF.RDB$FIELD_NAME = upper(:NEW_VW_FIELD)) = 0) then
  begin
    while (position('from', :VW_BODY, :J + 1) <> 0) do
    begin
      J = position('from', :VW_BODY, :J + 1);
      I = :I + 1;
    end

    if (:I = 1) then --один основной from, т.е. скрипт без подзапросов
    begin
      str = 'CREATE OR ALTER VIEW ' || upper(:VW_NAME) || '( ' || :VW_FIELDS || ',' || upper(:NEW_VW_FIELD) || ' ) as ' || substring(:VW_BODY from 1 for :J - 1) || ' ,' || upper(:NEW_VW_VALUE) || ' ' || substring(:VW_BODY from :J for char_length(:VW_BODY)) || '';
    end
    else
    begin --есть подзапросы - нужно распарсить и найти основной from
      J = 0;
      while (position('from', :VW_BODY, :J + 1) <> 0) do     --находим сколько всего from'ов в скрипте
      begin
        I = 0;
        J = position('from', :VW_BODY, :J + 1);
        L = 0;
        STR = substring(:VW_BODY from L + 1 for :J - 1);
        while (position('(', STR, :L + 1) <> 0) do       --считаем количество открывающих скобок
        begin
          L = position('(', STR, :L + 1);
          I = :I + 1;
        end

        L = 0;
        while (position(')', STR, :L + 1) <> 0) do       --считаем количество закрывающих скобок
        begin
          L = position(')', STR, :L + 1);
          I = :I - 1;
        end

        if (:I = 0) then --если открывающих и закрывающих поровну - значит этот from основной, если конечно в комментах нет лишних скобок
              str = 'CREATE OR ALTER VIEW ' || upper(:VW_NAME) || '( ' || :VW_FIELDS || ',' || upper(:NEW_VW_FIELD) || ' ) as ' || substring(:VW_BODY from 1 for :J - 1) || ' ,' || upper(:NEW_VW_VALUE) || ' ' || substring(:VW_BODY from :J for char_length(:VW_BODY)) || '';
      end
    end
   --if (position('where', substring(:VW_BODY from j+1))<>0) then
     -- str2 = substring(str from 1 for :j)||substring(str from j for position('where', substring(str from :j))-1)||' '||:new_vw_join;--||' '||substring(str from position('where', substring(str from :j)));
     execute statement str;  end
end^

SET TERM ; ^

/* Existing privileges on this procedure */

GRANT EXECUTE ON PROCEDURE PR_ALTER_VIEW TO SYSDBA;