Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Firebird, InterBase Новый топик    Ответить
 Изменить тело в процедурах  [new]
JohnyCage
Member

Откуда: Иркутск
Сообщений: 14
Коллеги, приветствую!
Просьба подсказать есть ли кого готовые решения или мысли как массово изменить тело процедур?
Задача следующая:
Требуется провести аудит по использованию процедур при формировании отчетов.
В БД насчитывается около 700 процедур для отчетов.
Первое, что пришло в голову это добавить строчку "insert into..." в тело процедуры после begin, но каждую править руками трудозатратно.
Спасибо.
6 окт 17, 04:05    [20846950]     Ответить | Цитировать Сообщить модератору
 Re: Изменить тело в процедурах  [new]
IBExpert
Member

Откуда: От верблюда
Сообщений: 2038
1. Извлечь код нужных процедур в скрипт ([CREATE OR] ALTER PROCEDURE).
2. Обработать полученный скрипт, вставив что положено куда следует.
3. Накатить скрипт на базу.
6 окт 17, 05:04    [20846956]     Ответить | Цитировать Сообщить модератору
 Re: Изменить тело в процедурах  [new]
JohnyCage
Member

Откуда: Иркутск
Сообщений: 14
IBExpert,

Александр, спасибо. Выполнил извлечение метаданных в IBExpert, но часть процедур экспортировались со следующим видом:
+
CREATE OR ALTER PROCEDURE RPT_PROC (
    FIELD1 INTEGER,
    FIELD2 INTEGER,
    FIELD3 DATE,
    FIELD4 DATE,
    FIELD5 DATE,
    FIELD6 DATE,
    FIELD7 INTEGER,
    FIELD8 INTEGER,
    FIELD9 INTEGER,
    FIELD10 INTEGER)
RETURNS (
    R_FIELD1 VARCHAR(30),
    R_FIELD2 VARCHAR(255),
    R_FIELD3 DOUBLE PRECISION,
    R_FIELD4 DOUBLE PRECISION,
    R_FIELD5 VARCHAR(30))
AS
BEGIN
  SUSPEND;
END;


Хотя в самой процедуре есть обработка данных.

Настройки в IBE
+

Картинка с другого сайта.
6 окт 17, 06:04    [20846964]     Ответить | Цитировать Сообщить модератору
 Re: Изменить тело в процедурах  [new]
fraks
Member

Откуда: Новосибирск
Сообщений: 1142
JohnyCage
Требуется провести аудит по использованию процедур при формировании отчетов.
В БД насчитывается около 700 процедур для отчетов.
Первое, что пришло в голову это добавить строчку "insert into..." в тело процедуры после begin, но каждую править руками трудозатратно.
Спасибо.


Что бы потом не править обратно, я бы вызывал не "insert into" а процедуру логирования, передавал бы в нее параметры, типа имя процедуры из которой вызывалось логирование. Тогда в процедуре логирования можно и данные перепихивать в разные места, если потребуется, и включать/выключать логирование на основании состояния генератора/переменной/записи в таблице.

Нужно - включил, не нужно - выключил. И это прямо на работающей базе, не меняя метаданных и управление сконцентрировано в одном месте.
6 окт 17, 06:35    [20846970]     Ответить | Цитировать Сообщить модератору
 Re: Изменить тело в процедурах  [new]
JohnyCage
Member

Откуда: Иркутск
Сообщений: 14
fraks,

Точно. Спасибо, так действительно будет лучше и удобнее.
6 окт 17, 06:50    [20846976]     Ответить | Цитировать Сообщить модератору
 Re: Изменить тело в процедурах  [new]
IBExpert
Member

Откуда: От верблюда
Сообщений: 2038
JohnyCage
Выполнил извлечение метаданных в IBExpert, но часть процедур экспортировались со следующим видом:


Это заглушки для разруливания зависимостей. Ищи ниже полные определения - они там есть. Вот эту часть нужно выделить и обработать.

А если сервер позволяет модифицировать системные таблицы напрямую, то можно просто пробежаться по RDB$PROCEDURES, вытащить RDB$PROCEDURE_SOURCE каждой нужной процедуры, найти в нем первый begin, вставить после него необходимое и апдейтить RDB$PROCEDURE_SOURCE. Затем просто перекомпилировать все процедуры и получить рабочий скрипт.
Разумеется, делать это нужно не на рабочей базе.
6 окт 17, 07:07    [20846981]     Ответить | Цитировать Сообщить модератору
 Re: Изменить тело в процедурах  [new]
JohnyCage
Member

Откуда: Иркутск
Сообщений: 14
IBExpert,

Спасибо. Буду пробовать.
6 окт 17, 07:23    [20846996]     Ответить | Цитировать Сообщить модератору
 Re: Изменить тело в процедурах  [new]
JohnyCage
Member

Откуда: Иркутск
Сообщений: 14
fraks,

А случайно не подскажете как получить имя выполняемой процедуры? информации чего-то не нашел...
6 окт 17, 10:46    [20847378]     Ответить | Цитировать Сообщить модератору
 Re: Изменить тело в процедурах  [new]
Василий №2
Guest
Хех, а я-то по названию темы подумал, что она о косметических процедурах для похудания )))

+ за отдельную процедуру лога

Изнутри процедуры получить ее имя никак нельзя, придется задавать константой
6 окт 17, 11:44    [20847576]     Ответить | Цитировать Сообщить модератору
 Re: Изменить тело в процедурах  [new]
JohnyCage
Member

Откуда: Иркутск
Сообщений: 14
Василий №2,

Так и думал. Благодарю. Буду тогда использовать совет Александра. (RDB$PROCEDURES)
6 окт 17, 12:21    [20847759]     Ответить | Цитировать Сообщить модератору
 Re: Изменить тело в процедурах  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 43657

JohnyCage
Требуется провести аудит по использованию процедур при формировании отчетов.

Для этого не требуется изменять тела процедур. Достаточно включить аудит.

Posted via ActualForum NNTP Server 1.5

6 окт 17, 12:31    [20847825]     Ответить | Цитировать Сообщить модератору
 Re: Изменить тело в процедурах  [new]
vvvait
Member

Откуда:
Сообщений: 19
Василий №2
Изнутри процедуры получить ее имя никак нельзя, придется задавать константой


да ладно, а как же MON$CALL_STACK
7 окт 17, 04:10    [20850252]     Ответить | Цитировать Сообщить модератору
 Re: Изменить тело в процедурах  [new]
afgm
Member

Откуда:
Сообщений: 545
vvvait
да ладно, а как же MON$CALL_STACK

К сожалению это не очень работоспособно.
7 окт 17, 19:22    [20851179]     Ответить | Цитировать Сообщить модератору
 Re: Изменить тело в процедурах  [new]
vvvait
Member

Откуда:
Сообщений: 19
afgm, отнюдь

create or alter procedure SET_CALLER_NAME
as
declare variable NM varchar(100);
declare variable TR integer;
begin
  TR = current_transaction;
  in autonomous transaction
  do select cs.MON$OBJECT_NAME
     from MON$CALL_STACK cs
     where exists(select *
            from MON$CALL_STACK cs1
            join MON$STATEMENTS s on s.MON$STATEMENT_ID = cs1.MON$STATEMENT_ID and s.MON$STATE = 1
            where s.MON$TRANSACTION_ID = :TR
              and upper(cs1.MON$OBJECT_NAME) = 'SET_CALLER_NAME'
              and cs1.MON$CALLER_ID = cs.MON$CALL_ID)
     into :NM;
  RDB$SET_CONTEXT('USER_TRANSACTION', 'CALLER_NAME', :NM);
end

create or alter procedure TEST_A
returns (NM varchar(100))
as
begin
  execute procedure SET_CALLER_NAME;
  NM = RDB$GET_CONTEXT('USER_TRANSACTION', 'CALLER_NAME');
  RDB$SET_CONTEXT('USER_TRANSACTION', 'CALLER_NAME', null);
  suspend;
end

create or alter procedure TEST_B
returns (NM varchar(100))
as
begin
  execute procedure SET_CALLER_NAME;
  NM = RDB$GET_CONTEXT('USER_TRANSACTION', 'CALLER_NAME');
  RDB$SET_CONTEXT('USER_TRANSACTION', 'CALLER_NAME', null);
  suspend;
end

select TEST_B.NM, TEST_A.NM
from TEST_B
join TEST_A on 0 = 0
8 окт 17, 03:11    [20851704]     Ответить | Цитировать Сообщить модератору
 Re: Изменить тело в процедурах  [new]
Roman Simakov
Member

Откуда:
Сообщений: 259
Dimitry Sibiryakov
JohnyCage
Требуется провести аудит по использованию процедур при формировании отчетов.

Для этого не требуется изменять тела процедур. Достаточно включить аудит.


Именно! Странно что больше никто не пишет и все изобретают костыли. Изучайте трейс. Это сильная штука.
8 окт 17, 09:55    [20851795]     Ответить | Цитировать Сообщить модератору
 Re: Изменить тело в процедурах  [new]
afgm
Member

Откуда:
Сообщений: 545
vvvait
afgm, отнюдь

А теперь потестим это на... не самой экстремальной нагрузке.
8 окт 17, 14:46    [20852149]     Ответить | Цитировать Сообщить модератору
 Re: Изменить тело в процедурах  [new]
vvvait
Member

Откуда:
Сообщений: 19
afgm, ну не знаю, лишних 0,5 - 1 мс это критично? может на куче коннектов будет похуже надо пробовать.
8 окт 17, 15:02    [20852169]     Ответить | Цитировать Сообщить модератору
 Re: Изменить тело в процедурах  [new]
afgm
Member

Откуда:
Сообщений: 545
vvvait
afgm, ну не знаю, лишних 0,5 - 1 мс это критично? может на куче коннектов будет похуже надо пробовать.

Для сложных обработок, где вызывается много процедур оверхед буде очень ощутимый.
Да и количество транзакция будет увеличиваться многократно, что может быть даже больнее.
8 окт 17, 19:28    [20852730]     Ответить | Цитировать Сообщить модератору
 Re: Изменить тело в процедурах  [new]
afgm
Member

Откуда:
Сообщений: 545
vvvait,
а вот и пример, показывающий, что многих коннектов не надо

-- Простая таблица
CREATE TABLE TEST_DATA_TABLE (
    ID       INTEGER,
    CAPTION  VARCHAR(50)
);

-- С триггером на вставку
CREATE OR ALTER TRIGGER TEST_DATA_TABLE_BI FOR TEST_DATA_TABLE
ACTIVE BEFORE INSERT POSITION 0
as
begin
  if (new.id is null) then
    new.id = gen_id(gen_test_data_table_id,1);
end

-- Вставляем такой процедуркой
create or alter procedure TEST_DATA_TABLE_INS (
    CAPTION varchar(50))
as
begin
  insert into TEST_DATA_TABLE (CAPTION)
  values (:CAPTION);
end

-- Сам код вставки
execute block as
declare variable n int = 10000;
begin
 while (n>0) do
 begin
    execute procedure test_data_table_ins('TEST_CAPTION');
    -- execute procedure SET_CALLER_NAME;
    n = n - 1;
 end
end

/*
ИТОГО:
Без получаения вызыввающего 94ms
С полученим вызывающего     10s 857ms
*/
8 окт 17, 19:41    [20852759]     Ответить | Цитировать Сообщить модератору
 Re: Изменить тело в процедурах  [new]
vvvait
Member

Откуда:
Сообщений: 19
afgm, ну это и есть 1 мс на вызов
8 окт 17, 21:32    [20853006]     Ответить | Цитировать Сообщить модератору
 Re: Изменить тело в процедурах  [new]
afgm
Member

Откуда:
Сообщений: 545
vvvait
afgm, ну это и есть 1 мс на вызов

Завит от нагрузки.
Снэпшот мониторинговых таблиц с высокой частотой - дорого
Пачка лишних транзакций - дорого
8 окт 17, 21:52    [20853032]     Ответить | Цитировать Сообщить модератору
Все форумы / Firebird, InterBase Ответить