Скачиваний:
16
Добавлен:
01.04.2014
Размер:
273.41 Кб
Скачать

16

ИСПОЛЬЗОВАНИЕ ПОДЗАПРОСОВ

С КОМАНДАМИ МОДИФИКАЦИИ

196 ПОНИМАНИЕ SQL ___________________________________________________________________

ГЛ. 16

В ЭТОЙ ГЛАВЕ, ВЫ УЗНАЕТЕ КАК ИСПОЛЬЗОВАТЬ

подзапросы в командах модификации.

Вы найдете, что нечто подобное - вы уже видели при использовании под-

запросов в запросах. Понимание, как подзапросы используются в коман-

дах SELECT, cделает их применение в командах модификации более уве-

ренным, хотя и останутся некоторые вопросы.

Завершением команды SELECT является подзапрос, но не предикат, и по-

этому его использование отличается от использования простых предика-

тов с командами модификации, которые вы уже выполняли ранеее с ко-

мандами UPDATE и DELETE. Вы использовали простые запросы чтобы

производить значения для INSERT, а теперь мы можем расширить эти

запросы чтобы включять в них подзапросы.

Важный принцип который надо соблюдать при работе с командами

модификации, состоит в том, что вы не можете в предложении FROM

любого подзапроса, модифицировать таблицу к которой ссылаетесь с

помощью основной команды. Это относится ко всем трем командам мо-

дификации. Хотя имеется большое количество ситуаций в которых будет

полезно сделать запрос той таблицы которую вы хотите модифицировать

причем во время ее модификации, это слишком усложняет операцию что-

бы использовать ее на практике.

Не делайте ссылки к текущей строке таблицы указанной в команде,

которая является соотнесенным подзапросом.

==== ИСПОЛЬЗОВАНИЕ ПОДЗАПРОСОВ С INSERT ===

INSERT - это самый простой случай. Вы уже видели как вставлять

результаты запроса в таблицу. Вы можете использовать подзапросы

внутри любого запроса, который генерирует значения для команды

INSERT тем же самым способом, которым вы делали это для других

запросов - т.е. внутри предиката или предложения HAVING.

Предположим, что мы имеем таблицу с именем SJpeople, столбцы

которой совпадают со столбцами нашей таблицы Продавцов.

Вы уже видели как заполнять таблицу подобно этой, заказчиками в

городе, например, в San Jose:

Insert into sJpeople

SELECT *

FROM Salespeople

WHERE city = 'San Jose';

ИСПОЛЬЗОВАНИЕ ПОДЗАПРОСОВ С КОМАНДАМИ МОДИФИКАЦИИ 197

______________________________________________________________________

Теперь мы можем использовать подзапрос чтобы добавить к таблице

SJpeople всех продавцов которые имеют заказчиков в San Jose, неза-

висимо от того, находятся ли там продавцы или нет:

Insert into sJpeople

SELECT *

FROM Salespeople

WHERE snum = ANY

( SELECT snum

FROM Customers

WHERE city = ' (San (Jose' );

Оба запроса в этой команде функционируют также как если бы они не

являлись частью выражения INSERT. Подзапрос находит все строки для

заказчиков в San Jose и формирует набор значений snum. Внешний запрос

выбирает строки из таблицы Salespeople, где эти значения snum найдены.

В этом примере, строки для продавцов Rifkin и Serres, которые назначены

заказчикам в San Jose - Liu и Cisneros, будут вставлены в таблицу SJpeople.

НЕ ВСТАВЛЯЙТЕ ДУБЛИКАТЫ СТРОК

Последовательность команд в предшествующем разделе может быть

проблематичной. Продавец Serres находится в San Jose, и следовательно

будет вставлен с помощью первой команды. Вторая команда попытается

вставить его снова, поскольку он имеет еще одного заказчика в San Jose.

Если имеются любые ограничения в таблице SJpeople которые вынужда-

ют ее значения быть уникальными, эта вторая вставка потерпит неудачу

( как это и должно было быть).

Двойные строки это плохо. ( См. Главу 18 для подробностей об ограниче-

ниях. )

Было бы лучше если бы вы могли как-то выяснить, что эти значения уже

были вставлены в таблицу, прежде чем вы попытаетесь сделать это снова,

с помощью добавления другого подзапроса ( использующего операторы

типа EXISTS, IN, < > ALL, и так далее ) к предикату.

К сожалению, чтобы сделать эту работу, вы должны будете сослаться на

саму таблицу SJpeople в предложении FROM этого нового подзапроса, а,

как мы говорили ранее, вы не можете ссылаться на таблицу которая

198 ПОНИМАНИЕ SQL

______________________________________________________________________

ГЛ. 16

задействована ( целиком ) в любом подзапросе команды модификации.

В случае INSERT, это будет также препятствовать соотнесенным подзапро-

сам, основанным на таблице в которую вы вставляете значения. Это имеет

значение, потому что, с помощью INSERT, вы создаете новую строку в таб-

лице. "Текущая строка" не будет существовать до тех пор, пока INSERT не

закончит ее обрабатывать.

ИСПОЛЬЗОВАНИЕ ПОДЗАПРОСОВ СОЗДАНЫХ

ВО ВНЕШНЕЙ ТАБЛИЦЕ ЗАПРОСА

Запрещение на ссылку к таблице которая модифицируется командой INSERT

не предохранит вас от использования подзапросов которые ссылаются к таб-

лице используемой в предложении FROM внешней команды SELECT. Таблица

из которой вы выбираете значения, чтобы произвести их для INSERT , не будет

задействована командой; и вы сможете ссылаться к этой таблице любым спосо-

бом которыми вы обычно это делали, но только если эта таблица указана в авто-

номном запросе. Предположим что мы имеем таблицу с именем Samecity в ко-

торой мы запомним продавцов с заказчиками в их городах.

Мы можем заполнить таблицу используя соотнесенный подзапрос:

Соседние файлы в папке ПОНИМАНИЕ SQL