|
Программирование >> Oracle
же). Если необходимо изменить все строки в таблице EMPSNT, придется выполнить 4 изменения (отдельно для каждой строки в таблице DEPT AND EMP), чтобы изменить виртуальную таблицу, связанную с каждой строкой. Необходимо также учесть, что при изменении данных о сотруднике отдела 10, семантически происходит изменение столбца EMPS таблицы DEPT AND EMP. Физически используется две таблицы, но семантически есть только одна. Хотя в таблице отделов данные не изменялись, строка, содержащая измененную вложенную таблицу, блокируется и не может быть изменена другими сеансами. При традиционной взаимосвязи главная/подчиненная такой проблемы нет. Вот почему я стараюсь не использовать вложенные таблицы для постоянного хранения данных. Лишь к немногим подчиненным таблицам запросы отдельно не выполняются. В рассмотренном примере таблица ЕМР - отдельная, самостоятельная сущность и должна запрашиваться отдельно. Так бывает практически всегда. Я обычно использую вложенные таблицы в представлениях на основе реляционных таблиц. Подробно мы будем рассматривать это в главе 20, посвященной объектно-реляционным возможностям. Теперь, когда вы знаете, как изменять экземпляр вложенной таблицы, вставка и удаление из нее строк не составит трудностей. Давайте добавим строку в экземпляр вложенной таблицы для отдела 10 и удалим одну из строк для отдела 20: tkyte@TKYTE816> insert into table 2 (select emps from dept and emp where deptno = 10) 3 values 4 (1234, NewEmp, CLERK, 7782 , sysdate, 1200, null); 1 row created. tkyte@TKYTE816> delete from table 2 (select emps from dept and emp where deptno 3 where ename = SCOTT; 1 row deleted. tkyte@TKYTE816> select d.dname, e.empno, ename 2 from dept and emp d, table(d.emps) e 3 where d.deptno in (10, 20);
Итак, вот базовый синтаксис операторов для запросов и изменения вложенных таблиц. Оказывается, для использования вложенные таблицы часто приходится извлекать (как пришлось это делать мне в рассмотренных примерах), особенно при выполнении запросов. Усвоив концепцию виртуальная таблица для каждой строки , вы упростите себе работу с вложенными таблицами. Сначала я категорически утверждал: Необходимо всегда выполнять соединение, нельзя получить данные только из таблицы ЕМР , а затем смягчился: Вообще-то можно, если очень хочется . Этот метод не описан в документации и не поддерживается, так что используйте его только как последнюю надежду, если ничего другого не остается. Наиболее удобен он в случаях, когда необходимо выполнить множественное изменение данных во вложенной таблице (помните, нам приходилось делать это через таблицу DEPT путем соединения). Есть недокументированная подсказка, NESTED TABLE GET REFS, используемая утилитами ЕХР и IMP для работы с вложенными таблицами. Ее использование также позволяет лучше понять физическую структуру вложенных таблиц. Эту волшебную подсказку легко обнаружить после экспортирования таблицы с вложенной таблицей. Я экспортировал представленную выше таблицу, чтобы получить ее расширенное определение с помощью утилиты IMP. После экспортирования в разделяемом пе (в представлении V$SQL) я обнаружил следующий SQL-оператор: SELECT /* + NESTED TABLE GET REFS + */ NESTED TABLE ID, SYS HC ROWINFO$ FROM TKYТЕ . EMPS NT Найти его позволил простой запрос вида SELECT SQL TEXT FROM V$SQL WHERE UPPER(SQL TEXT) LIKE %EMP%. Если выполнить найденный SQL-опе-ратор, можно получить волшебные результаты: tkyte@TKYTE816> SELECT /*+NESTED TABLE GET REFS+*/ 2 NESTED TABLE ID, SYS NC ROWINFO$ 3 FROM TKYTE . EMPS NT NESTED TABLE ID SYS NC ROWINFO$ (EMPNO, ENAME, 9A39835005B149859735617476C9A80E EMP TYPE(7782, CLARK, MANAGER, 7839, 09-JUN-81, 2450, 100) 9A39835005B149859735617476C9A80E EMP TYPE(7839, KING, PRESIDENT, MU 17-NOV-81, 5000, 100) Да, несколько удивительно, ведь если получить описание таблицы: tkyte@TKYTE816> desc enps nt Name Null? Type EMPNO NUMBER (4) ENAME VARCHAR2 (10) JOB VARCHAR2(9) MGR NUMBER (4) HIREDATE DATE SAL NUMBER(7,2) COMM NUMBER (7,2) этих двух столбцов в нем вообще нет. Они являются частью скрытой реализации вложенных таблиц. Столбец NESTED TABLE ID фактически является внешним ключом к главной таблице DEPT AND EMP. Таблица DEPT AND EMP имеет скрытый столбец, используемый для соединения с таблицей EMPSNT. Столбец SYS NC ROWINF$ - магический. Это скорее функция, а не столбец. Вложенная таблица в данном случае является объектной (она построена по объектному типу), a SYS NC INFO$ - внутренний способ ссылки на строку как на объект (вместо отдельных ссылок на все реляционные столбцы) в базе данных Oracle. За кулисами сервер Oracle автоматически реализовал отношение главная/подчиненная между таблицами, с первичный и внешним ключами, сгенерированными системой. Если покопаться еше, можно добраться до реального словаря данных, и получить информацию обо всех столбцах таблицы DEPT AND EMP: tkyte@TKYTE816> select name 2 from sys.col$ 3 where obj# = (select object id 4 from user objects 5 where object name = DEPT AKD EMP) NAME DEPTNO DNAME EMPS SYS NC0000400005$ tkyte@TKYTE816> select SYS NC0000400005$ from dept and emp; SYS NC0000400005$ 9A39835005B149859735617476C9A80E A7140089B1954B39B73347EC20190D68 20D4AA0839FB49B097 5FBDE367 842E16 56350C866BA24ADE8CF9E47073C52296 Столбец со странным именем SYS NC0000400005$ - это сгенерированный системой ключ для таблицы DEPT AND EMP. Если продолжить исследование, можно выяснить, что сервер Oracle создал по этому столбцу уникальный индекс. К сожалению, однако, он не проиндексировал столбец NESTED TABLE ID в таблице EMPS NT. Этот столбец надо проиндексировать, поскольку всегда выполняется соединение из таблицы DEPT AND EMP с таблицей EMPS NT. Об этом важно помнить при использовании стандартных вложенных таблиц, как в рассмотренном ранее примере: всегда индексируйте столбец NESTED TABLE ID вложенных таблиц!
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |