Программирование >>  Oracle 

1 ... 94 95 96 [ 97 ] 98 99 100 ... 469


Я немного отвлекся от темы. Итак, мы говорили о том, каким образом можно работать с вложенной таблицей, как с обычной. Это делается с помощью подсказки NESTED TABLE GET REFS. Ее можно использовать так:

tkyte@TKYTE816> select /*+ nested table get refs */ empno, ename

2 front emps nt where ename like %A% ;

EMPNO ENAME

7782 CLARK

7876 ADAMS

7499 ALLEN

7521 WARD

7654 MARTIN 7698 BLAKE 7900 JAMES 7 rows selected.

tkyte@TKYTE816> update /*+ nested table get refs */ emps nt 2 set ename = initcap(ename);

14 rows updated.

tkyte@TKYTE816> select /*+ nested table get refs */ empno, ename 2 from emps nt where ename like %a%;

EMPKO ENAME

7782 Clark 7876 Adams 7521 Ward 7654 Martin 7698 Blake 7900 James 6 rows selected.

Повторю еще раз: эта возможность не отражена в документации и официально не поддерживается. Она может использоваться не во всех средах. Речь идет о специфической функциональной возможности, обеспечивающей работу утилит ЕХР и IMP. Это единственная среда, где она гарантированно работает. Используйте эту подсказку на свой страх и риск. Используйте, однако, осторожно, и не включайте в производственный код. Используйте ее для разовых исправлений данных или для получения содержимого вложенной таблицы. Официально поддерживается только извлечение данных столбца в виде таблицы следующим образом:

tkyte@TKYTE816> select d.deptno, d.dname, emp.*

2 from dept and emp D, table(d.emps) emp

Именно этот прием следует использовать в запросах и в производственном коде.




Хранение вложенных таблиц

Кое-что о том, как хранится вложенная таблица, нам уже известно. Сейчас мы чуть глубже рассмотрим стандартно создаваемую сервером Oracle структуру, а также параметры, которыми можно управлять. Вернемся к рассмотренному ранее оператору создания таблицы:

tkyte@TKYTE816> create table dept and emp

2 (deptno number(2) primary key,

3 dname varchar2(14),

4 loc varchar2(13),

5 emps emp tab type

7 nested table emps store as emps nt; Table created.

tkyte@TKYTE816> alter table emps nt add constraint emps empno unique

2 unique(empno)

Table altered.

Мы знаем, что фактически сервер Oracle создает следующую структуру:

Dept and Emp

DEPTNO

DNAME LOC

SYS NC0000400005$

NUMBER(2)-

VARCHAR2 (14) VARCHAR2 (13) RAW (16)

> SYS C001788

SYS C001787

EmpsNT

SYS C001789

SYS NC ROWINFO$

NESTEDJTABLEJD

EMPNO

ENAME

HIREDDATE

COMM

RAW (16) NUMBER (4) VARCHAR2 (10) VARCHAR2 (9) NUMBER (4)

DATE

NUMBER (7.2) NUMBER (7,2)

Создается две таблицы. Таблица, создаваемая явно, получила дополнительный скрытый столбец (по умолчанию скрытый столбец будет создаваться для каждого столбца типа вложенной таблицы). По этому скрытому столбцу создается также требование уникальности. Сервер Oracle автоматически создал вложенную таблицу EMPS NT. Эта таблица включает два скрытых столбца, причем один из них, SYS NC ROWINFO$, - виртуальный; он возвращает все скалярные элементы в виде объекта. Второй столбец -внешний ключ, NESTED TABLE ID, по которому вложенную таблицу можно соеди-



нять с главной. Обратите внимание на отсутствие индекса по этому столбцу! Наконец, сервер Oracle добавил индекс по столбцу DEPTNO в таблице DEPT AND EMP для ограничения первичного ключа. Итак, мы хотели создать таблицу, но получили намного больше. Если разобраться, создаются практически те же структуры, что и для поддержки отношения главная/подчиненная таблица, но в последнем случае мы бы использовали существующий первичный ключ по столбцу DEPTNO в качестве внешнего ключа в таблице EMPS NT, а не генерировали бы суррогатный ключ типа RAW(16).

Если поинтересоваться, как сохраняют нашу вложенную таблицу утилиты EXP/IMP, можно увидеть следующее:

CREATE TABLE TKYTE . DEPT AND EMP ( DEPTNO NUMBER(2, 0), DKAME VARCHAR2(14) , LOC VARCHAR2(13),

EMPS EMP TAB TYPE )

PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 LOGGING STORAGE(INITIAL 131072 NEXT 131072

MINEXTENTS 1 MAXEXTENTS 4096 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER POOL DEFAULT) TABLESPACE USERS NESTED TABLE EMPS STORE AS EMPS NT RETURN AS VALUE

Единственная новая конструкция здесь - RETURN AS VALUE. Она описывает, как вложенная таблица возвращается клиентскому приложению. По умолчанию сервер Oracle передает вложенную таблицу клиенту по значению: вместе с каждой строкой передаются фактические данные. Можно также задать RETURN AS LOCATOR, что означает возвращать клиенту указатель на данные (локатор), а не сами данные. Данные будут передаваться только после того, как клиент разыменует этот указатель. Поэтому, если предполагается, что клиент не будет просматривать строки вложенной таблицы для каждой строки основной таблицы, можно возвращать указатель, а не значения, уменьшая объем передаваемой по сети информации. Например, если клиентское приложение отображает список отделов, а при двойном щелчке на строке отдела - информацию о его сотрудниках, имеет смысл использовать указатель. Детальная информация о сотрудниках обычно не просматривается. Но этот случай скорее исключение, чем правило.

Что еще можно сделать с вложенной таблицей? Во-перв1х, столбец NESTED TABLE ID необходимо проиндексировать. Поскольку к вложенной таблице обращаются из главной как к подчиненной, этот индекс действительно необходим. Можно проиндексировать этот столбец с помощью оператора CREATE INDEX, но лучше хранить вложенную таблицу как организованную по индексу. Вложенная таблица - еще один прекрасный пример использования таблицы, организованной по индексу. При этом все подчиненные строки будут физически объединяться по значению столбца NESTED TABLE ID (так что извлечение данных потребует меньше операций физического ввода/вывода). При этом также не нужно создавать дополнительный индекс по столбцу RAW(16). Если оптимизировать дальше, то, поскольку столбец



1 ... 94 95 96 [ 97 ] 98 99 100 ... 469

© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика