В завершение знакомства с меточным доступом к строкам в Oracle мне хотелось бы подчеркнуть, что даже без учета структуры меток, привилегий, группирования пользователей и многого прочего, большая часть которого в этих статьях не рассматривалась, мандатный метод доступа не так прямолинеен в поведении, как мог бы показаться поначалу.
Рассмотрим обычную выдачу данных, помеченных метками доступа. Вспомним, что до сих пор в таблице PHONE у нас имелось по одному номеру телефона на каждого сотрудника. Попробуем добавить второй телефон Аллену, а так как сценарий phones.sql использует для выдачи на экран полуоткрытое соединение, употребление его останется корректным и для этих новых данных. Интерес представляет случай, когда телефоны Аллена (когда их станет два) будут иметь метку LIMITED, и когда к ним обратится пользователь EMPLOYEE. Интуиция подсказывает, что «невидимые» телефоны Аллена будут обрабатываться полуоткрытым соединением подобно пропущенному значению (NULL), и в результате выборки мы увидим несколько строк для Аллена с пропущенными значениями номеров телефона. А что на самом деле?
Добавим в таблицу PHONE для Аллена новый телефон и «засекретим» оба:
CONNECT head/head
INSERT INTO scott.phone SELECT empno, '111-2222', empsec_label FROM scott.phone WHERE empno = (SELECT empno FROM scott.emp WHERE ename='ALLEN')
@updateallen LIMITED
Проверяем:
SQL> @phones
ENAME PNO ---------- -------------------- SMITH 665-7282 ALLEN 111-2222 ALLEN 882-3154 WARD 610-1718 JONES 100-6539 MARTIN 103-1983 BLAKE 193-3112 CLARK 310-2673 SCOTT 680-4853 KING 542-6672 TURNER 293-1398 ADAMS 278-5105 JAMES 932-6728 FORD 485-9127 MILLER 865-6706
15 rows selected.
SQL> CONNECT employee/employee Connected. SQL> @phones
ENAME PNO ---------- -------------------- ALLEN
WARD 610-1718 MARTIN 103-1983 BLAKE CLARK KING TURNER 293-1398 JAMES 932-6728 MILLER 865-6706
9 rows selected.
Меточный доступ в Oracle справедливо показал пользователю EMPLOYEE имя Аллена (его строка в таблице EMP в открытом доступе), и не показал его телефоны (мы закрыли доступ к телефонам Аллена в таблице PHONE), но вот только открытое соединение таблиц EMP и PHONE показало "отсутствие" (на деле - недоступность) телефона одной строкой, а не двумя! Ничего лишнего: телефон недоступен, а сколько их недоступно - не сообщается. Если же сделать один из телефонов Аллена открытым, информация о наличии второго, недоступного телефона и вовсе пропадет:
SQL> CONNECT head/head Connected. SQL> UPDATE scott.phone 2 SET 3 empsec_label 4 = CHAR_TO_LABEL ( 'empsec_policy', 'OPEN' ) 5 WHERE 6 pno = '111-2222'
7 /
1 row updated.
SQL> CONNECT employee/employee Connected. SQL> @phones
ENAME PNO ---------- -------------------- ALLEN 111-2222
WARD 610-1718 MARTIN 103-1983 BLAKE CLARK KING TURNER 293-1398 JAMES 932-6728 MILLER 865-6706
9 rows selected.
Не думаю, что такое поведение для всех очевидно, а значит приведенные выше примеры могут оказаться небесполезными.