|
Программирование >> Oracle
tkyte@TKYTE816> insert into dept and emp 2 select dept.*, 3 CAST(multiset(select empno, ename, job, mgr, hiredate, sal, comm 4 from SCOTT.EMP 5 where emp.deptno = dept.deptno) AS emp tab type) 6 from SCOTT.DEPT 4 rows created. Здесь хочу обратить ваше внимание на две особенности. Создано только четыре строки. Действительно, в таблице DEPT AND EMP - только четыре строки. 14 строк таблицы ЕМР отдельно не существуют. Синтаксис становится весьма экзотичным. Ключевые слова CAST и MULTISET разработчики обычно никогда не используют. При работе с объектно-реляционными возможностями базы данных придется использовать много экзотических синтаксических конструкций. Ключевое слово MULTISET используется, чтобы сообщить серверу Oracle, что подзапрос может вернуть несколько строк (подзапросы в списке выбора оператора SELECT ранее могли возвращать только одну строку). Оператор CAST используется, чтобы преобразовать возвращаемое множество в тип набора; в данном случае с помощью CAST мы преобразуем многоэлементное множество (MULTISET) в данные типа EMP TAB TYPE. Оператор CAST позволяет выполнять преобразование типов в общем случае, не только для наборов. Например, если необходимо извлечь столбец EMPNO из таблицы ЕМР как данные типа VARCHAR2(20), а не NUMBER(4), можно выполнить запрос select cast(empno as VARCHAR2(20)) e emp. Теперь все готово для запроса данных. Давайте посмотрим, как выглядит одна строка таблицы: tkyte@TKYTE816> select deptno, dname, loc, d.emps AS employees 2 from dept and emp d 3 where deptno = 10 DEPTNO DNAME LOC EMPLOYEES (EMPNO, ENAME, JOB, M 10 ACCOUNTING NEW YORK EMP TAB TYPE (EMP TYPE (7782, CLARK, MANAGER, 7839, 09-JUN-81, 2450, NOLL), EMP TYPE{7839, KING, PRESIDENT, NULL, 17-NOV-81, 5000, NULL), EMP TYPE(7934, MILLER , CLERK, 7782, 23-JAN-82, 1300, NULL)) Все данные здесь, в одном столбце. Большинство приложений, если только они не учитывают объектно-реляционные возможности специально, не смогут работать с та- ким столбцом. Например, интерфейс ODBC не предоставляет средств для работы с вложенными таблицами (JDBC, OCI, Pro*C, PL/SQL и большинство других прикладных программных интерфейсов такие средства включают). В подобных случаях сервер Oracle позволяет извлечь вложенный набор и работать с ним, как с обычной реляционной таблицей. Например: tkyte@TKYTE816> select d.deptno, d.dname, emp.* 2 from dept and emp D, table(d.emps) emp
Можно преобразовать столбец EMPS в таблицу, и при этом естественно и автоматически произойдет соединение; условия соединения задавать не надо. Поскольку наш тип ЕМР вообще не включает столбец DEPTNO, соединять, собственно не по чему. Сервер Oracle учитывает этот нюанс автоматически. Итак, как же изменить данные? Предположим, необходимо установить комиссионные в объеме 100 долларов всем сотрудникам 10 отдела. Это можно сделать так: tkyte@TKYTE816> update 2 3 4 table (select emps from dept and emp where deptno set comm 3 rows updated. Вот здесь и вступает в игру виртуальная таблица для каждой строки . В условии оператора SELECT, показанном ранее, было не совсем очевидно, что для каждой строки есть таблица значений, поскольку никаких соединений и прочих подобных конструкций в запросе не было. Все выполнялось как бы чудесным образом. Оператор UPDATE, однако, показывает, что для каждой строки есть таблица. Мы выбрали отдельную таб- лицу для изменения; у этой таблицы нет имени - только идентифицирующий ее запрос. Если бы использовался запрос SELECT, не возвращающий только одну таблицу, были бы выданы сообщения об ошибках: tkyte@TKYTE816> update 2 table(select emps 3 from dept and emp 4 where deptno = 1 6 set com = 100 update * ERROR at line 1: ORA-22908: reference to NULL table value tkyte@TKYTE816> update 2 table(select emps 3 from dept and emp 4 where deptno > 1 6 set comm = 100 table(select emps * ERROR at line 2: ORA-01427: single-row subquery returns more than one row Если возвращается менее одной строки (одного экземпляра вложенной таблицы), изменение завершается сообщением об ошибке. Обычно изменение нуля строк - это нормально, но в данном случае выдается такое же сообщение об ошибке, как если бы не было указано имя изменяемой таблицы. Если возвращается несколько строк (более одного экземпляра вложенной таблицы), изменение тоже завершается сообщением об ошибке. Обычно изменение нескольких строк вполне допустимо. Это показывает, что сервер Oracle рассматривает каждую строку в таблице DEPT AND EMP в качестве указателя на другую таблицу, а не просто набора строк, как в реляционной модели. В этом состоит семантическое отличие вложенной таблицы от пары реляционных таблиц, связанных отношением главная/подчиненная. В случае вложенной таблицы имеется отдельная таблица для каждой родительской строки. Это различие иногда может усложнить работу с вложенными таблицами. Рассмотрим используемую модель, наглядно представляющую данные для одного отдела. Но она абсолютно не подходит для запросов типа: В каком отделе работает KING? , Сколько бухгалтеров работает в организации? и тому подобных. Эти запросы лучше выполнять к реляционной таблице ЕМР, но в нашей модели с вложенной таблицей добраться до данных таблицы ЕМР можно только через данные таблицы DEPT. Всегда надо выполнять соединение - нельзя запросить данные только из таблицы ЕМР. Сделать это стандартным и описанным в документации способом нельзя, но можно использовать один трюк (подробнее о нем - поз-
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |