Дейт К. Д27 Руководство по реляционной субд db2/ Пер с англ и предисл. М. Р. Когаловского

Вид материалаРуководство
Глава 6 манипулирование данными iii: операции обновления 6.1. введение
6.2. Предложение update
6.2.1. Обновление единственной записи
6.2.2. Обновление множества записей
6.2.3. Обновление с подзапросом
6.2.4. Обновление нескольких таблиц
6.3. Предложение delete
6.3.1. Удаление единственной записи
6.3.2. Удаление множества записей
6.3.4. Удаление с подзапросом
6.4. Предложение insert
6.4.1. Вставка единственной записи
6.4.2. Вставка единственной записи с опущенными именами полей
6.4.3. Вставка единственной записи
6.4.4. Вставка множества записей
6.4.5. Использование insert... select для построения внешнего соединения
Ответы к некоторым упражнениям
Подобный материал:
1   2   3   4   5   6   7   8   9   10   ...   34

ГЛАВА 6

МАНИПУЛИРОВАНИЕ ДАННЫМИ III:

ОПЕРАЦИИ ОБНОВЛЕНИЯ

6.1. ВВЕДЕНИЕ



В двух последних главах весьма подробно было рассмотрено предложение выборки данных SELECT языка SQL. Обратим теперь наше внимание на предложения обновления данных UPDATE (обновить), DELETE (удалить) и INSERT (вставить). Примечание. Термин «обновить» имеет, к сожалению, в системе DB2 два различных смысла. Он используется как родовой термин для ссылки на все три указанные операции как класс, а с другой стороны, специально для ссылки на операцию UPDATE саму по себе. Для того чтобы различать эти два смысла в данной книге, рассматриваемый термин записывается строчными буквами, когда предполагается его использование в родовом смысле, и прописными, если имеется в виду специфический его смысл.

Как и предложение SELECT, три предложения обновления данных оперируют не только базовыми таблицами, но и представлениями. Однако по причинам, рассмотрение которых выходит за рамки данной главы, не все представления являются обновляемыми. Если пользователь попытается выполнять операцию обновления над необновляемым представлением, система DB2 просто отвергнет эту операцию с соответствующим сообщением для пользователя. Предположим, следовательно, для целей данной главы, что все таблицы, которые будут обновляться, являются базовыми таблицами, а рассмотрение запросов к представлениям и, в частности, обновления представлений отложим до главы 8.

В следующих трех разделах подробно обсуждаются три операции обновления. Синтаксис этих операций следует тому же общему образцу, который был уже показан для операции SELECT. Для удобства в начале соответствующих разделов приводится в общих чертах синтаксис обсуждаемых предложений языка SQL.

6.2. ПРЕДЛОЖЕНИЕ UPDATE



Предложение UPDATE имеет следующий общий формат:

UPDATE таблица

SET поле = выражение

[,поле = выражение] . . .

[WHERE предикат];

Все записи в «таблице», которые удовлетворяют «предикату», обновляются в соответствии с присваиваниями «поле = выражение» во фразе SET (установить).

6.2.1. ОБНОВЛЕНИЕ ЕДИНСТВЕННОЙ ЗАПИСИ


Изменить цвет детали Р2 на желтый, увеличить ее вес на 5 и установить значение города «неизвестен» (NULL).

UPDATE P

SET ЦВЕТ = 'Желтый',

ВЕС = ВЕС + 5,

ГОРОД = NULL

WHERE НОМЕР_ДЕТАЛИ = 'Р2';

Для каждой записи, которая должна быть обновлена (т. е. для каждой записи, которая удовлетворяет предикату WHERE, или для всех записей, если фраза WHERE опущена), ссылки во фразе SET на поля этой записи обозначают значения этих полей перед тем, как будет выполнено какое-либо присваивание в этой фразе SET.

6.2.2. ОБНОВЛЕНИЕ МНОЖЕСТВА ЗАПИСЕЙ


Удвоить состояние всех поставщиков, находящихся в Лондоне.

UPDATE S

SET СОСТОЯНИЕ = 2*СОСТОЯНИЕ

WHERE ГОРОД = 'Лондон';

6.2.3. ОБНОВЛЕНИЕ С ПОДЗАПРОСОМ


Установить объем поставок равным нулю для всех поставщиков из Лондона.

UPDATE SP

SET КОЛИЧЕСТВО = О

WHERE 'Лондон' =

(SELECT ГОРОД FROM S

WHERE S. НОМЕР_ПОСТАВЩИКА =

SP. НОМЕР_ПОСТАВЩИКА);

6.2.4. ОБНОВЛЕНИЕ НЕСКОЛЬКИХ ТАБЛИЦ


Изменить номер поставщика S2 на S9.

UPDATE S

SET НОМЕР_ПОСТАВЩИКА = 'S9'

WHERE НОМЕР_ПОСТАВЩИКА = 'S2';

UPDATE SP

SET НОМЕР_ПОСТАВЩИКА = 'S9'

WHERE НОМЕР_ПОСТАВЩИКА = 'S2';

Невозможно обновить более одной таблицы в единственном запросе. Иными словами, в предложении UPDATE должна специфицироваться в точности одна таблица. Поэтому в данном примере мы сталкиваемся со следующей проблемой целостности (точнее, с проблемой целостности по ссылкам): база данных становится противоречивой после выполнения первого предложения UPDATE — она включает теперь некоторые поставки, для которых не имеется соответствующей записи о поставщике, и остается в таком состоянии до тех пор, пока не будет выполнено второе предложение UPDATE. Изменение порядка предложений UPDATE, конечно, не решает эту проблему. Поэтому важно обеспечить выполнение обоих этих предложений, а не только одного. Этот вопрос о поддержании целостности в условиях, когда требуется множество обновлений, детально обсуждается в главе 11. Кроме того, проблема целостности по ссылкам, в частности, подробно описана в Приложении А, а использованный в системе DB2 подход к ее решению представлен в Приложении В.

6.3. ПРЕДЛОЖЕНИЕ DELETE



Предложение DELETE имеет следующий общий формат:

DELETE

FROM таблица

[WHERE предикат];

Удаляются все записи в «таблице», которые удовлетворяют «предикату».

6.3.1. УДАЛЕНИЕ ЕДИНСТВЕННОЙ ЗАПИСИ


Удалить поставщика S1.

DELETE

FROM S

WHERE НОМЕР_ПОСТАВЩИКА = 'S1’.

И снова, если таблица SP в настоящее время содержит какие-либо поставки для поставщика S1, это удаление нарушит непротиворечивость базы данных (сравните с примером 6.2.4; как и в случае предложения UPDATE, нет операций DELETE, воздействующих на несколько таблиц). См. главу 11, а также Приложения А и В.

6.3.2. УДАЛЕНИЕ МНОЖЕСТВА ЗАПИСЕЙ


Удалить всех поставщиков из Лондона.

DELETE

FROM S ,

WHERE ГОРОД = 'Лондон';

6.3.3. УДАЛЕНИЕ МНОЖЕСТВА ЗАПИСЕЙ


Удалить все поставки.

DELETE

FROM SP;

SP — все еще известная таблица, но она теперь пуста. Удалить все записи—это не уничтожить таблицу (операция DROP).

6.3.4. УДАЛЕНИЕ С ПОДЗАПРОСОМ


Удалить все поставки для поставщиков из Лондона.

delete

FROM SP

WHERE 'Лондон' =

(SELECT ГОРОД

FROM S

WHERE S. НОМЕР_ПОСТАВЩИКА =

SP. НОМЕР_ПОСТАВЩИКА);

6.4. ПРЕДЛОЖЕНИЕ INSERT



Предложение INSERT имеет следующий общий формат:

INSERT

INTO таблица [(поле [,поле] . . .)]

VALUES (константа [,константа] . . .);

ИЛИ:

INSERT

INTO таблица [(поле [,поле] . . .)]

подзапрос;

В первом формате в «таблицу» вставляется строка, имеющая заданные значения для указанных полей, причем 1-я константа в списке констант соответствует i-му полю в списке полей. Во втором формате вычисляется «подзапрос»; копия результата, представляющего собой, вообще говоря, множество строк, вставляется в «таблицу». При этом 1-й столбец этого результата соответствует f-му полю в списке полей. В обоих случаях отсутствие списка полей эквивалентно спецификации списка всех полей в таблице (см. ниже пример 6.4.2).

6.4.1. ВСТАВКА ЕДИНСТВЕННОЙ ЗАПИСИ


Добавить в таблицу Р деталь Р7 (город 'Атенс', вес — 2, название и цвет в настоящее время неизвестны).

Insert

INTO Р (НОМЕР_ДЕТАЛИ, ГОРОД, BEC)

VALUES ('Р7', 'Атенс', 2);

Создается новая запись для детали с заданным номером, городом и весом, с неопределенными значениями для названия и цвета. Эти два последних поля не должны быть, конечно, определены как NOT NULL в предложении CREATE TABLE для таблицы Р. Порядок слева — направо, в котором поля указаны в предложении INSERT, не обязательно должен совпадать с порядком слева — направо, в котором поля были специфицированы в предложении CREATE (или ALTER).

6.4.2. ВСТАВКА ЕДИНСТВЕННОЙ ЗАПИСИ С ОПУЩЕННЫМИ ИМЕНАМИ ПОЛЕЙ


Добавить деталь Р8 в таблицу Р, при этом: название—'Звездочка', цвет — 'Розовый', вес— 14, город — 'Ницца'.

INSERT

INTO P

VALUES ('Р8', 'Звездочка', 'Розовый', 14, 'Ницца');

Отсутствие списка полей эквивалентно спецификации списка всех полей в таблице в порядке слева — направо, как они были определены в предложении CREATE (или ALTER). Как и «SELECT * », такая краткая нотация может быть удобной для интерактивного SQL. Она потенциально опасна, однако, во встроенном SQL, т. е. в предложениях SQL, используемых в прикладной программе, в связи с тем, что предполагаемый список полей может изменяться, если для программы заново осуществляется связывание, а определение таблицы было в этом промежутке времени изменено.

6.4.3. ВСТАВКА ЕДИНСТВЕННОЙ ЗАПИСИ


Вставить новую поставку с номером поставщика S20, номером детали Р20 и количеством 1000.

INSERT

INTO SP (НОМЕР—ПОСТАВЩИКА, НОМЕР—ДЕТАЛИ, КОЛИЧЕСТВО)

VALUES ('S20', 'Р20', 1000);

Подобно операциям UPDATE и DELETE операция INSERT при отсутствии соответствующего управления также может порождать проблему целостности по ссылкам (см. главу 11, а также Приложения А и В). В рассматриваемом случае система DB2 не проверяет, имеется ли поставщик S20 в таблице S и деталь Р20 в таблице Р.

6.4.4. ВСТАВКА МНОЖЕСТВА ЗАПИСЕЙ


Для каждой поставляемой детали получить ее номер и общий объем поставок, сохранить результат в базе данных (см. пример 5.4.7).

CREATE TABLE ВРЕМЕННАЯ

(НОМЕР_ДЕТАЛИ CHAR (6),

ОБЪЕМ_ПОСТАВКИ INTEGER);

INSERT

INTO ВРЕМЕННАЯ (НОМЕР_ДЕТАЛИ, ОБЪЕМ_ПОСТАВКИ)

SELECT НОМЕР_ДЕТАЛИ, SUM (КОЛИЧЕСТВО)

FROM SP

GROUP BY НОМЕР_ДЕТАЛИ;

Здесь предложение SELECT выполняется точно так же, как обычно, но результат не возвращается пользователю, а копируется в таблицу ВРЕМЕННАЯ. Теперь с этой копией пользователь может делать все, что он пожелает — делать дальнейшие запросы, печатать и даже обновлять ее. Никакая из этих операций не будет оказывать какого-либо влияния на первоначальные данные. В конечном счете таблицу ВРЕМЕННАЯ можно будет уничтожить, когда она больше не будет нужна:

DROP TABLE ВРЕМЕННАЯ;

Предыдущий пример очень хорошо показывает, почему свойство замкнутости реляционных систем, обсуждаемое во введении к разделу 4.2, является таким важным. Приведенная полная процедура работает именно в связи с тем, что результатом предложения SELECT является другая таблица. Она не работала бы, если бы результат был чем-либо иным, кроме таблицы.

Между прочим, целевая таблица вовсе не обязательно должна быть первоначально пустой для вставки множества записей, хотя в приведенном примере это так. Если таблица не пуста, новые записи просто добавляются к тем, которые уже имеются.

Одно из важных применений INSERT.. .SELECT — построение так называемого внешнего соединения. Как указывалось в главе 4, обычное (естественное) соединение двух таблиц не включает в результате строк какой-либо из двух таблиц, для которых нет соответствующих строк в другой таблице. Например, обычное соединение таблиц S и Р по городам не включает какой-либо строки для поставщика S5 или для детали РЗ, поскольку в Атенсе не хранится никакая деталь и нет поставщиков, находящихся в Риме (см. пример 4.3.1). Следовательно, в некотором смысле можно считать, что при обычном соединении теряется информация для таких несоответствующих строк. Однако иногда может потребоваться способность сохранять эту информацию. Рассмотрим следующий пример.

6.4.5. ИСПОЛЬЗОВАНИЕ INSERT... SELECT ДЛЯ ПОСТРОЕНИЯ ВНЕШНЕГО СОЕДИНЕНИЯ


Для каждого поставщика получить его номер, фамилию, состояние и город вместе с номерами всех поставляемых им деталей, Если данный поставщик не поставляет вообще никаких деталей, то выдать информацию для этого поставщика, оставляя в результате пробелы вместо номера детали.

CREATE TABLE ВНЕШ_СОЕДИНЕНИЕ

(НОМЕР_ПОСТАВЩИКА CHAR (5),

ФАМИЛИЯ CHAR (20),

СОСТОЯНИЕ SMALLINT,

ГОРОД CHAR (15)),

НОМЕР_ДЕТАЛИ CHAR (6);

INSERT

INTO ВНЕШ_СОЕДИНЕНИЕ

SELECT S.*, SP.HOMEP_ДЕТАЛИ

FROM S, SP

WHERE S. НОМЕР_ПОСТАВЩИКА=SP. НОМЕР_ПОСТАВЩИКА;

INSERT

INTO ВНЕШ_СОЕДИНЕНИЕ

SELECT S.*, 'bb'

FROM S

WHERE NOT EXISTS

(SELECT *

FROM SP

WHERE SP. НОМЕР_ПОСТАВЩИКА=

S. НОМЕР_ПОСТАВЩИКА);

Теперь таблица BHEШ_СОЕДИНЕНИЕ выглядит так:

ВНЕШ_СОЕДИНЕНИЕ

НОМЕР_

ПОСТАВЩИКА

ФАМИЛИЯ

СОСТОЯНИЕ

ГОРОД

НОМЕР_

ДЕТАЛИ




S1

S1

S1

S1

S1

S1

S2

S2

S3

S4

S4

S4

S5

Смит

Смит

Смит

Смит

Смит

Смит

Джонс

Джонс

Блейк

Кларк

Кларк

Кларк

Адамc

20

20

20

20

20

20

10

10

30

20

20

20

30

Лондон

Лондон

Лондон

Лондон

Лондон

Лондон

Париж

Париж

Париж

Лондон

Лондон

Лондон

Атенс

Р1

Р2

РЗ

Р4

Р5

Р6

Р1

Р2

Р2

Р2

Р4

Р5

bb


Здесь 'bb' используется для представления строки пробелов. Пояснение. Первые двенадцать строк приведенного результата, как легко видеть, соответствуют первому из двух INSERT.. .SELECT и представляют собой обычное естественное соединение таблиц S и SP по номерам поставщиков, за исключением того, что не включен столбец КОЛИЧЕСТВО. Последняя строка результата соответствует второму INSERT.. .SELECT и сохраняет информацию для поставщика S5, который не поставляет никаких деталей. Полный результат представляет собой внешнее соединение таблиц S и SP по номерам поставщиков, в котором опущен столбец КОЛИЧЕСТВО. В противоположность этому обычное соединение называется иногда внутренним соединением.

Заметим, что нужны два отдельных INSERT.. .SELECT, поскольку подзапрос не может содержать UNION.

6.5. ЗАКЛЮЧЕНИЕ



Мы подошли к концу детального обсуждения четырех предложений манипулирования данными—SELECT, UPDATE, DELETE и INSERT. Сложности этих предложений (и достаточно серьезные!) связаны, по большей части, с предложением SELECT. Как Вы могли убедиться, после того как достигнуто достаточное понимание предложения SELECT, другие предложения становятся довольно понятными. Конечно, на практике предложение SELECT обычно бывает также довольно простым.

Однако, вопреки сказанному выше, с операциями обновления также связаны две проблемы, которые заслуживают, чтобы о них здесь упомянуть.

— Первой и более важной является проблема целостности по ссылкам, которую мы уже несколько раз затрагивали. Как уже указывалось, в Приложениях А и В содержится основательное обсуждение этой проблемы.

— Вторая проблема состоит в том, что более сложным формам трех предложений обновления свойственно следующее небольшое ограничение. Если фраза WHERE в предложении UPDATE или DELETE включает подзапрос, то во фразе FROM этого подзапроса не должна упоминаться целевая таблица этого UPDATE или DELETE. Аналогичным образом в форме предложения INSERT с подзапросом во фразе FROM в подзапросе не должна упоминаться таблица, которая является целевой для этого предложения INSERT. Так, например, если нужно удалить всех поставщиков, состояние которых меньше среднего, то следующий запрос не будет работать.

DELETE

FROM S

WHERE СОСТОЯНИЕ <

(SELECT AVG (СОСТОЯНИЕ)

FROM S);

Вместо этого нужно последовательно выполнить следующие шаги:

SELECT AVG (СОСТОЯНИЕ)

FROM S:

Результат:

22


В соответствии с этим:

DELETE

FROM S

WHERE СОСТОЯНИЕ < 22;

Для указанных ограничений нет каких-либо внутренне присущих причин. Они являются просто следствием способа реализации рассматриваемых операций в системе DB2.

В заключение укажем, что наличие в языке SQL лишь четырех операций манипулирования данными — одна из причин легкости использования этого языка. В свою очередь тот факт, что имеется лишь четыре таких операции, является следствием простоты реляционной структуры данных. Как указывалось в главе 1, все данные в реляционной базе данных представляются совершенно одинаковым образом как значения в позициях столбцов и строк таблиц. Поскольку имеется только один способ представления всех данных, необходима лишь одна операция для каждой из четырех базисных функций (выбрать, изменить, вставить, удалить). В противоположность этому в системах, основанных на более сложных структурах данных, теоретически требуется 4n операций, где n — число способов представления данных в такой системе. Например, в системах, основанных на концепциях КОДАСИЛ, где данные могут быть представлены либо как записи, либо как связи между записями, можно обычно обнаружить операцию STORE (запомнить) для создания записи и операцию CONNECT (включить) для создания связи, операцию ERASE (стереть) для уничтожения записи и операцию DISCONNECT (исключить) для уничтожения связи, операцию MODIFY (модифицировать) для изменения записи и операцию RECONNECT (переключить) для изменения связи и т. д. На самом деле системы типа КОДАСИЛ обычно предусматривают более двух способов представления данных, но записи и связи — наиболее важные из них.

УПРАЖНЕНИЯ



Как обычно, все следующие упражнения основаны на базе данных поставщиков-деталей-изделий:

S (НОМЕР_ПОСТАВЩИКА, ФАМИЛИЯ, СОСТОЯНИЕ, ГОРОД)

Р (НОМЕР_ДЕТАЛИ, НАЗВАНИЕ, ЦВЕТ, ВЕС, ГОРОД)

J (НОМЕР_ИЗДЕЛИЯ, НАЗВАНИЕ, ГОРОД)

SPJ (НОМЕР_ПОСТАВЩИКА, НОМЕР_ДЕТАЛИ, НОМЕР_ИЗДЕЛИЯ, КОЛИЧЕСТВО)

Запишите подходящее предложение INSERT, DELETE или UPDATE для каждой из следующих задач.

6.1. Измените цвет всех красных деталей на оранжевый.

6.2. Удалите все изделия, для которых нет поставок деталей.

6.3. Увеличьте размер поставки на 10 процентов для всех поставок тех поставщиков, которые поставляют какую-либо красную деталь.

6.4. Удалите все изделия из Рима и все соответствующие поставки.

6.5. Вставьте в таблицу S нового поставщика S10. Его фамилия и город — 'Уайт' и 'Нью-Йорк' соответственно, а состояние еще неизвестно.

6.6. Постройте таблицу, содержащую список номеров деталей, которые поставляются либо каким-нибудь поставщиком из Лондона, либо для какого-либо изделия в Лондоне.

6.7. Постройте таблицу, содержащую список номеров изделий, которые либо находятся в Лондоне, либо для них поставляются детали каким-нибудь поставщиком из Лондона.

6.8. Добавьте 10 к состоянию всех поставщиков, состояние которых в настоящее время меньше, чем состояние поставщика S4.

6.9. Постройте внешнее естественное соединение изделий и поставок по номерам изделий.

6.10. Постройте внешнее естественное соединение деталей и изделий по городам.

6.11. Постройте таблицу, содержащую полную информацию о поставщиках, деталях и изделиях, с указанием объема поставок для каждой поставки вместе с «сохраненной» информацией для каждого поставщика, детали и изделия, которые не входят в таблицу поставок (о смысле понятия «сохраненная информация» в этом контексте см. пример 6.4.5).

ОТВЕТЫ К НЕКОТОРЫМ УПРАЖНЕНИЯМ



Как обычно, следующие решения не обязательно являются единственно возможными.

6.1. UPDATE P

SЕТ ЦВЕТ = 'Оранжевый'

WHERE ЦВЕТ = 'Красный';

6.2. DELETE

FROM J

WHERE НОМЕР_ПОСТАВЩИКА NOT IN

(SELECT НОМЕР_ИЗДЕЛИЯ

FROM SPJ);

6.3. CREATE TABLE КРАСНЫЕ

(НОМЕР_ПОСТАВЩИКА CHAR(5));

INSERT INTO КРАСНЫЕ (НОМЕР_ПОСТАВЩИКА)

SELECT DISTINCT НОМЕР_ПОСТАВЩИКА

FROM SPJ, P

WHERE SPJ. НОМЕР_ДЕТАЛИ = P. НОМЕР_ДЕТАЛИ

AND ЦВЕТ = 'Красный';

UPDATE SPJ

SET КОЛИЧЕСТВО = КОЛИЧЕСТВО * 1.1

WHERE НОМЕР_ПОСТАВЩИКА IN

(SELECT НОМЕР_ПОСТАВЩИКА

FROM КРАСНЫЕ);

DROP TABLE КРАСНЫЕ;

Заметим, что следующее «решение» с помощью одного предложения некорректно. Почему?

UPDATE SPJ

SET КОЛИЧЕСТВО = КОЛИЧЕСТВО * 1.1

WHERE НОМЕР_ПОСТАВЩИКА IN

(SELECT DISTINCT НОМЕР_ПОСТАВЩИКА

FROM SPJ, P

WHERE SPJ. НОМЕР_ДЕТАЛИ = Р. НОМЕР_ДЕТАЛИ

AND P. ЦВЕТ = 'Красный');

6.4. DELETE

FROM SPJ

WHERE 'Рим'=

(SELECT ГОРОД

FROM J

WHERE J.HOMEP_ИЗДЕЛИЯ=SPJ. НОМЕР_ИЗДЕЛИЯ);

DELETE

FROM J

WHERE ГОРОД == 'Рим';

6.5. INSERT

INTO S (НОМЕР_ПОСТАВЩИКА, ФАМИЛИЯ. ГОРОД)

VALUES ('S10', 'Уайт', 'Нью-Йорк');

или;

INSERT

INTO S (НОМЕР_ПОСТАВЩИКА, ФАМИЛИЯ, СОСТОЯНИЕ, ГОРОД)

VALUES ('S10', 'Уайт', 'NULL', 'Нью-Йорк');

6.6. CREATE TABLE СПИСОК_ДЕТАЛЕЙ

(НОМЕР_ДЕТАЛИ CHAR (6));

INSERT INTO СПИСОК_ДЕТАЛЕЙ (НОМЕР_ДЕТАЛИ)

SELECT DISTINCT НОМЕР_ДЕТАЛИ

FROM SPJ

WHERE НОМЕР_ПОСТАВЩИКА IN

(SELECT НОМЕР_ПОСТАВЩИКА

FROM S

WHERE ГОРОД = 'Лондон')

OR НОМЕР_ИЗДЕЛИЯ IN

(SELECT НОМЕР_ИЗДЕЛИЯ

FROM J

WHERE ГОРОД = 'Лондон');

6.7. CREATE TABLE СПИСОК_ИЗДЕЛИЙ (НОМЕР_ИЗДЕЛИЯ CHAR (4));

INSERT INTO СПИСОК_ИЗДЕЛИЙ (НОМЕР_ИЗДЕЛИЯ

SELECT НОМЕР_ИЗДЕЛИЯ

FROM J

WHERE ГОРОД == 'Лондон'

OR НОМЕР_ИЗДЕЛИЯ IN

(SELECT DISTINCT HOMEP_ИЗДЕЛИЯ

FROM SPJ

WHERE НОМЕР_ПОСТАВЩИКА IN

(SELECT НОМЕР_ПОСТАВЩИКА

FROM S

WHERE ГОРОД = 'Лондон'));

Замечание. Следующее решение некорректно:

INSERT INTO СПИСОК_ИЗДЕЛИЙ (НОМЕР_ИЗДЕЛИЯ)

SELECT НОМЕР_ИЗДЕЛИЯ

FROM J

WHERE ГОРОД = 'Лондон'

UNION

SELECT DISTINCT НОМЕР_ИЗДЕЛИЯ

FROM SPJ

WHERE 'Лондон' =

(SELECT ГОРОД

FROM S

WHERE S. НОМЕР_ПОСТАВЩИКА =

SPJ НОМЕР_ПОСТАВЩИКА);

Операция UNION никогда не допускается в подзапросе (в любом контексте).

6.8. SELECT СОСТОЯНИЕ

FROM S

WHERE НОМЕР_ПОСТАВЩИКА = 'S4';

Результат:

СОСТОЯНИЕ

20

Отсюда:

UPDATE S

SET СОСТОЯНИЕ = СОСТОЯНИЕ +10

WHERE СОСТОЯНИЕ < 20;

6.9. CREATE TABLE РЕЗУЛЬТАТ9

(НОМЕР_ИЗДЕЛИЯ CHAR(4),

НАЗВАНИЕ CHAR(IO),

ГОРОД CHAR(15)

НОМЕР_ПОСТАВЩИКА CHAR(5),

НОМЕР_ДЕТАЛИ CHAR(6),

КОЛИЧЕСТВО INTEGER);

INSERT

INTO РЕЗУЛЬТАТ9

SELECT J.*, SPJ. НОМЕР_ПОСТАВЩИКА,

SPJ. НОМЕР_ДЕТАЛИ, SPJ. КОЛИЧЕСТВО

FROM J, SPJ

WHERE J. НОМЕР_ИЗДЕЛИЯ = SPJ. НОМЕР_ИЗДЕЛИЯ;

INSERT

INTO РЕЗУЛЬТАТ9

SELECT J.*, 'bb', 'bb','0

FROM J

WHERE NOT EXISTS

(SELECT *

FROM SPJ

WHERE SPJ.HOMEP_ИЗДЕЛИЯ = J.HOMEP_ ИЗДЕЛИЯ);

6.10. CREATE TABLE PEЗУЛЬTAT10

(НОМЕР_ДЕТАЛИ CHAR(6),

НАЗВАНИЕ CHAR (20),

ЦВЕТ CHAR (6),

ВЕС SMALLINT,

ГОРОД SHAR(15),

НОМЕР_ИЗДЕЛИЯ CHAR(4),

НАЗВАНИЕ CHAR(10));

INSERT

INTO РЕЗУЛЬТАТ10

SELECT P.*, НОМЕР_ИЗДЕЛИЯ, НАЗВАНИЕ

FROM Р, J

WHERE Р. ГОРОД = J. ГОРОД;

INSERT

INTO РЕЗУЛЬТАТ10

SELECT Р. *, bb', bb'

FROM P

WHERE NOT EXISTS

(SELECT *

FROM J

WHERE J. ГОРОД = Р. ГОРОД);

INSERT

INTO РЕЗУЛЬТАТ10

SELECT 'bb', 'bb', 'bb', 0, J.ГОРОД, J.НОМЕР_

ИЗДЕЛИЯ, J.НАЗВАНИЕ

FROM J

WHERE NOT EXISTS

(SELECT *

FROM P

WHERE P. ГОРОД = J. ГОРОД);

6.11. CREATE TABLE РЕЗУЛЬТАТ11

(НОМЕР_ПОСТАВЩИКА . . ., ФАМИЛИЯ . . ., СОСТОЯНИЕ . . ., ГОРОД_ПОСТАВЩИКА . . ., НОМЕР_ДЕТАЛИ .... НАЗВАНИЕ_ДЕТАЛИ . . , ЦВЕТ . . ., ВЕС . . ., ГОРОД_ДЕТАЛИ . . ., НОМЕР_ИЗДЕЛИЯ . . ., НАЗВАНИЕ_ИЗДЕЛИЯ .... ГОРОД_ИЗДЕЛИЯ . . ., КОЛИЧЕСТВО . . .);

INSERT INTO РЕЗУЛЬТАТ 11

SELECT S. *, P. *, J. *, SPJ. КОЛИЧЕСТВО

FROM S, P, J, SPJ

WHERE S. НОМЕР_ПОСТАВЩИКА = SPJ.НОМЕР_ПОСТАВЩИКА

AND P. НОМЕР_ДЕТАЛИ = SPJ. НОМЕР_ДЕТАЛИ

AND J. НОМЕР_ИЗДЕЛИЯ = SPJ. НОМЕР_ИЗДЕЛИЯ;

INSERT INTO РЕЗУЛЬТАТ11

SELECT S. *, 'bb', ‘bb', 'bb', 0, ‘bb', 'bb', ‘bb', 'bb', 0

FROM S

WHERE NOT EXISTS

(SELECT *

FROM SPJ

WHERE SPJ. НОМЕР_ПОСТАВЩИКА = S. НОМЕР_ПОСТАВЩИКА);

INSERT INTO РЕЗУЛЬТАТ 11

SELECT 'bb', 'bb', 0, 'bb', P. *, 'bb', 'bb', 'bb', 0

FROM P

WHERE NOT EXISTS

(SELECT *

FROM SPJ

WHERE P. НОМЕР_ДЕТАЛИ = SPJ. НОМЕР_ДЕТАЛИ);

INSERT INTO РЕЗУЛЬТАТ 11

SELECT 'bb', 'bb', 0, 'bb', 'bb', 'bb', 'bb', 0, 'bb', J. *, 0

FROM J

WHERE NOT EXISTS

(SELECT *

FROM SPJ

WHERE SPJ.НОМЕР_ИЗДЕЛИЯ = J.НОМЕР_ИЗДЕЛИЯ);