Я собираюсь сделать некоторые предположения, но если ни один из них не решит вашу проблему, вам нужно будет найти диагностическую информацию, которую предоставляет база данных.ORA-28112 создаст файл трассировки в каталоге user_dump_dest
на сервере базы данных.Это должно дать вам всю информацию, необходимую для диагностики и исправления любых ошибок в коде вашей политики.Если у вас нет доступа к этому каталогу, вам нужно будет попросить помочь вашу дружную команду администраторов баз данных / системного администратора.
Итак, предположения.
Вы устанавливаете vv_dept
встрока 'dept = SYS_CONTEXT(''payroll_ctx'', ''dept'')'
.В блоке IF вы объединяете это с фильтром предложения WHERE.Итак, ваша последняя строка на самом деле:
DEPT =dept = SYS_CONTEXT('payroll_ctx', 'dept')
(Она никогда не выполнит ветвь DEPT !=
, потому что вы присваиваете эту строку vv_dept
, не выполняя ее, поэтому vv_dept
никогда не может быть равным 'Accounting'
.)
Это явно неправильно, и поэтому неудивительно, что Oracle швыряет ORA-28112.К счастью, решение в равной степени очевидно: просто приведите в порядок присваивание vv_dept
:
vv_dept := SYS_CONTEXT('payroll_ctx', 'dept');
Другая вещь, на которую стоит обратить внимание, - это форматирование самой политики.Вы проверяете равенство строки, поэтому вам нужно заключить ее в кавычки, чтобы получить правильный SQL:
payroll_pred := 'DEPT =''' || vv_dept ||'''';
И, очевидно, то же самое для другой ветви.
Еще одинвещь, чтобы рассмотреть.Если вы входите в систему как пользователь, которого нет в таблице payroll
(не уверен, возможно ли это), вы выполняете это:
WHEN NO_DATA_FOUND THEN NULL;
Следовательно, у этого сеанса нет установленного контекста, что означает, что функция политики потерпит неудачу, есливпоследствии пользователь пытается запросить payroll
.Лучшим подходом было бы установить контекст с нулевым значением для dept
, затем в политику добавить тест для vv_dept is null
, который применяет 1=2
или что-то подобное.
ORA-06502:PL / SQL: ошибка с числовым значением или значением: буфер символьной строки слишком мал
Что ж, вы наверняка получите это, если будете использовать опубликованный код sec_fun
, потому что вы определили vv_dept
как varchar2(20)
и назначенная строка длиннее двадцати символов.Но вы говорите, что запускаете мои предложенные изменения, так что этого не может быть.Какой размер payroll.dept
?
Последнее слово.
Политики VPD являются особым случаем динамического SQL, и основной принцип остается неизменным: динамический SQL сложен, потому что он превращает ошибки компиляции в ошибки времени выполнения.Точно так же основной инструмент отладки все еще записывает дескриптор выполнения, который записывает всю собранную строку в таблицу (или файл).
Кстати, я думаю, что в бизнес-логике есть изъян.В настоящее время никто не может просмотреть записи для бухгалтерии (кроме опытных пользователей с привилегией EXEMPT ACCESS POLICY
).