Oracle sql triggers :old :new обращение по заранее не известному полю
а не проще ли переделать процедуру save_to_history, чтобы она рекорды принимала? =/
Вопроса не понял, но может execute immediate поможет?
у него свой контекст. в пл/сиквеле нет замыканий. передать переменные в контекст можно, но для этого нужно к ним по имени обращаться же, а ТС от этого и хочет избавиться. ^_^
Это я то же не понял.
Пишешь compaund trigger который
after each row сохраняет id изменяемой записи во внутренний массив.
after statement делает селект из таблицы по массивы сохранённых id и пишет куда-то в историю.
На вход: имя таблицы,
На выход: таблица следующего вида
TableName FieldName Value Row
-------------------------------------------------
По сути таблица для транспортирования данных
Реализация на ABAP языке.
На вход tableName.
Определения переменных опущены.
field-symbols: <val> type any
,<table> type any table
,<line> type any
,<text> type any
.
select * "берем имена всех колонок для таблицы
from dd03l
into table fldName
where tabname = tabName
.
create data commonTableRef type table of (tabName).
assign commonTableRef->* to <table>. "создаем табличку заданного типу
select * "заполняем ее
from (tabName)
into table <table>
.
row = 1.
loop at <table> assigning <line>. "идем по таблице
loop at fldName into fldNameLine. "идем по колонкам
clear: dotLine.
assign component fldNameLine-fieldName of structure <line> to <text>. "АНАЛОГ ЭТОГО Я ИЩУ В PL/SQL
dotLine-id = dotId. "Заполняем все нужные поля выходной таблицы
dotLine-table = tabName.
dotLine-field = fldNameLine-fieldName.
dotLine-value = <text>.
append dotLine to dot.
endloop.
row = row + 1.
endloop.
По поводу моего первого поста:
Я знаю имя таблицы.
По нему я могу получить имена всех ее колонок(столбцов).
Далее я хочу сделать цикл по всем именам колонок (переменная forVariable):
Дай мне из :new то, что лежит в колонке с именем forVariable
Тебе надо просто отслеживать изменения в таблице, и, когда меняется значение в некотором столбце писать в лог
<имя таблицы> <имя столбцы> <старое> <новое>
Или же
<имя таблицы> <список всех полей + старые значения> <список всех полей + новые значения>
Или речь вообще не о логировании?
сдаётся мне, тут классический случайsad but true
Что-то у меня подозрение, что новый велосипед рождается.У меня тоже
Тебе надо просто отслеживать изменения в таблице, и, когда меняется значение в некотором столбце писать в логименно так
<имя таблицы> <имя столбцы> <старое> <новое>
в общем ответ на твой вопрос нет, в оракле нет таких возможностей. по крайней мере мне они не известны, и гугл тоже не знает. да и просто очевидно, что этого не может быть, потому что порядок записей в рекорде может быть разный в зависимости от того, какой запрос вернул этот рекорд. так что итерацию по номеру поля в рекорде реализовать нельзя.
Том Кайт.
Проблема в том что :new и \:old это не record, это псевдозапись.
Это конечно не правда. Например, Проблема в том что :new и \:old это не record, это псевдозапись.
Как отслеживать изменения в таблице? и, когда меняется значение в некотором столбце писать в лог:
<имя таблицы> <имя столбца> <старое> <новое>?
Решения которые я обдумывал:
1. навесить на таблицу обычный тригер, в этом случае я не знаю как обратиться к :new.(Какое-то значение, заранее не известное)
2. Сделать составной тригер, во время обработки строки (before/after for each row кидать во внутренний массив id,
после обработки строк, делать select из таблицы по заданным id, кидать эту запись в лог2 (в формате <имя таблицы> <имя столбца> <новое значение> ).
При случае нужный формат (<имя таблицы> <имя столбца> <старое> <новое>) я смогу восстановить.
Я так понимаю, что во втором варианте я смогу реализовать формат лог2 ( <имя таблицы> <имя столбца> <новое значение> тк в этот момент я могу делать select из измененной таблицы и не имею дел с псевдозаписями?
1. навесить на таблицу обычный тригер, в этом случае я не знаю как обратиться к :new.(Какое-то значение, заранее не известное)Это просто не возможно.
Я так понимаю, что во втором варианте я смогу реализовать формат лог2 ( <имя таблицы> <имя столбца> <новое значение> тк в этот момент я могу делать select из измененной таблицы и не имею дел с псевдозаписями?Я не уверен, но может удастся получить и старые значения вызвав процедуру с pragma AUTONOMOUS_TRANSACTION.
Но что-то мне кажется гораздо проще написать ddl-триггер который будет переписывать dml-триггер, если структура таблицы изменяется.
Но что-то мне кажется гораздо проще написать ddl-триггер который будет переписывать dml-триггер, если структура таблицы изменяется.Спасибо, так и реализую.
Спасибо всем кто отписался =)
Оставить комментарий
uaha1979
Пишу тригер по типу "BEFORE INSERT OR UPDATE OR DELETE", там есть в псевдозаписи : old :new, я могу обращаться к полям по имени например : old.id.Вопрос: могу ли я обращаться по полю, которое не известно к моменту компиляции?
Например:
вместо того чтобы писать
Написать нечто вроде:
функция save_to_history просто добавляет строки (имя поля, старое значение, новое значение) в базу данных.