ORACLE. Динамическое исправление кода процедуры
(скриптом).
Вот такая была задача: необходимо было изменить на базе код множества процедур. Изменения были простенькие - но ошибок быть не должно. Код процедур во внешних источниках не хранился. Достаточно было изменить на базе и все. Возникла такая идея: «А нельзя ли поменять скриптом?»
Оказывается можно (я и сам удивлялся).
Предположим имеем процедуру
create or replace function pmu_proba
return number
is
nKuku number;
begin
nKuku := 100;
return nKuku;
end pmu_proba;
Запрос select pmu_proba from dual понятное дело, возвращает 100.
Теперь выполним вот такой запрос (с commit -ом естественно)
update sys.source$ t
set t.source = replace(t.source, '100', '200')
where t.Obj# = (select object_id
from all_objects t
where t.Object_Name = 'PMU_PROBA')
and trim(t.Source) like 'nKuku%:=%100;%'
Потом выполним вот такую команду:
alter procedure pmu_proba compile
Теперь запрос select pmu_proba from dual возвращает 200.
Что интересно, после update sys.source$ состояние процедуры не меняется на INVALID, что приводит к интересным побочным эффектам.
Допустим, мы сделаем все тоже самое, что и раньше, но не выполним alter procedure pmu_proba compile. Тогда select pmu_proba from dual будет возвращать 100 что до, что после изменения текста процедуры. Пользуясь такой особенностью можно, кстати, заложить на БД мину. Допустим эта процедура зависит от какого-нибуть объекта (ну, там вызывает другую процедуру, или еще что). Мы меняем ей текст таким образом, чтобы в ней была заведомо ошибка (допустим, как в нашем случае nKuku := 100 меняем на nTutu := 100 ), но процедуру не компилируем. Теперь допусим, кто-то когда нибудь изменить объект, от которого зависит наша процедура. Она, понятно стане инвалидной. Но после компиляции она все равно останется инвалидной!. Естественно, изменения объекта откатят и снова перекомпилят нашу процедуру. Но она так и останется инвалидной.
Вот такие пироги.
НО! Как говорится, «Минздрав предупреждает!»
Если у Вас официально купленный Oracle то так делать категорически не стоит! Как я только что узнал (слава Богу - не на своей шкуре), что при использовании такого метода база переходит в unsupport mode и оракловый support отказывает Вам в поддержке. Как они об этом узнают и что значит "переходит в unsupport mode" я точно не знаю. Но вот ссылка на форум sql.ru где я задавал этот вопрос.
|