Удаление единственной записи
Удалить поставщика S1.
DELETE
FROM S
WHERE НОМЕР_ПОСТАВЩИКА = ’S1’;
И снова, если таблица SP в настоящее время содержит какие-либо поставки для поставщика S1, это удаление нарушит непротиворечивость базы данных.
Удаление множества записей
Удалить всех поставщиков из Лондона.
DELETE
FROM S
WHERE ГОРОД = ’Лондон’;
Удаление множества записей
Удалить все поставки.
DELETE
FROM SP;
SP — все еще известная таблица, но она теперь пуста. Удалить все записи — это не уничтожить таблицу (операция
DROP).
Удаление с подзапросом
Удалить все поставки для поставщиков из Лондона.
DELETE
FROM SP
WHERE ’Лондон’ =
(SELECT ГОРОД FROM S
WHERE S.НОМЕР_ПОСТАВЩИКА = SP.НОМЕР_ПОСТАВЩИКА);
306
Предложение insert
Предложение INSERT имеет следующий общий формат:
INSERT
INTO таблица [(поле [, поле] …)] VALUES (константа [, константа] …);
или:
INSERT
INTO таблица [(поле [, поле] …)] подзапрос;
В первом формате в «таблицу» вставляется строка, имеющая заданные значения для указанных полей, причем 1-я константа в списке констант соответствует 1-му полю в списке полей. Во втором формате вычисляется «подзапрос»; копия результата, представляющего собой, вообще говоря, множество строк, вставляется в «таблицу». При этом 1-й столбец этого результата соответствует 1-му полю в списке полей. В обоих случаях отсутствие списка полей эквивалентно спецификации списка всех полей в таблице.
Вставка единственной записи
Добавить в таблицу Р деталь Р7 (город 'Атенс', вес — 2, название и цвет в настоящее время неизвестны).
INSERT
INTO Р (НОМЕР_ДЕТАЛИ, ГОРОД, ВЕС)
VALUES (’Р7’, ’Атенс’, 2);
Создается новая запись для детали с заданным номером, городом и весом, с неопределенными значениями для названия и цвета. Эти два последних поля не должны быть, конечно, определены как NOT NULL в предложении CREATE TABLE для таблицы Р. Порядок слева — направо, в котором поля указаны в предложении INSERT, не обязательно должен совпадать с порядком слева — направо, в котором поля были
307
специфицированы в предложении CREATE (или ALTER).
Вставка единственной записи с опущенными именами полей
Добавить деталь Р8 в таблицу Р, при этом: название — ’Звездочка’, цвет — ’Розовый’, вес — 14, город — ’Ницца’.
INSERT
INTO Р
VALUES (’Р8’, ’Звездочка’, ’Розовый’, 14, ’Ницца’);
Отсутствие списка полей эквивалентно спецификации списка всех полей в таблице в порядке слева — направо, как они были определены в предложении CREATE (или ALTER). Как и «SELECT * », такая краткая нотация может быть удобной для интерактивного SQL. Она потенциально опасна, однако, во встроенном SQL, т. е. в предложениях SQL, используемых в прикладной программе, в связи с тем, что предполагаемый список полей может изменяться, если для программы заново осуществляется связывание, а определение таблицы было в этом промежутке времени изменено.
Вставка единственной записи
Вставить новую поставку с номером поставщика S20, номером детали Р20 и количеством 1000.
INSERT
INTO SP (НОМЕР_ПОСТАВЩИКА, НОМЕР_ДЕТАЛИ, КОЛИЧЕСТВО)
VALUES (’S20’, ’Р20’, 1000);
Подобно операциям UPDATE и DELETE операция INSERT при отсутствии соответствующего управления также может порождать проблему целостности по ссылкам.
308
Вставка множества записей
Для каждой поставляемой детали получить ее номер и общий объем поставок, сохранить результат в базе данных.
CREATE TABLE ВРЕМЕННАЯ
(НОМЕР_ДЕТАЛИ CHAR (6), ОБЪЕМ_ПОСТАВКИ INTEGER);
INSERT
INTO ВРЕМЕННАЯ (НОМЕР_ДЕТАЛИ, ОБЪЕМ_ПОСТАВКИ) SELECT НОМЕР_ДЕТАЛИ, SUM (КОЛИЧЕСТВО)
FROM SP
GROUP BY НОМЕР_ДЕТАЛИ;
Здесь предложение SELECT выполняется точно так же, как обычно, но результат не возвращается пользователю, а копируется в таблицу ВРЕМЕННАЯ. Теперь с этой копией пользователь может делать все, что он пожелает — делать дальнейшие запросы, печатать и даже обновлять ее. Никакая из этих операций не будет оказывать какого-либо влияния на первоначальные данные. В конечном счете, таблицу ВРЕМЕННАЯ можно будет уничтожить, когда она больше не будет нужна:
DROP TABLE ВРЕМЕННАЯ;
Предыдущий пример очень хорошо показывает, почему свойство замкнутости реляционных систем, является таким важным. Приведенная полная процедура работает именно в связи с тем, что результатом предложения SELECT является другая таблица. Она не работала бы, если бы результат был чемлибо иным, кроме таблицы.
Между прочим, целевая таблица вовсе не обязательно должна быть первоначально пустой для вставки множества записей, хотя в приведенном примере это так. Если таблица не пуста, новые записи просто добавляются к тем, которые уже имеются.
309
Одно из важных применений INSERT … SELECT — построение так называемого внешнего соединения. Обычное (естественное) соединение двух таблиц не включает в результате строк какой-либо из двух таблиц, для которых нет соответствующих строк в другой таблице. Например, обычное соединение таблиц S и Р по городам не включает какой-либо строки для поставщика S5 или для детали Р3, поскольку в Атенсе не хранится никакая деталь и нет поставщиков, находящихся в Риме. Следовательно, в некотором смысле можно считать, что при обычном соединении теряется информация для таких несоответствующих строк. Однако иногда может потребоваться способность сохранять эту информацию. Рассмотрим следующий пример.
Использование insert ... select для построения внешнего соединения
Для каждого поставщика получить его номер, фамилию, состояние и город вместе с номерами всех поставляемых им деталей. Если данный поставщик не поставляет вообще никаких деталей, то выдать информацию для этого поставщика, оставляя в результате пробелы вместо номера детали.
CREATE TABLE ВНЕШ_СОЕДИНЕНИЕ (НОМЕР_ПОСТАВЩИКА CHAR (5),
ФАМИЛИЯ CHAR (20),
СОСТОЯНИЕ SMALLINT,
ГОРОД CHAR (15),
НОМЕР_ДЕТАЛИ CHAR (6);
INSERT
INTO ВНЕШ_СОЕДИНЕНИЕ
SELECT S.*, SP.НОМЕР_ДЕТАЛИ FROM S, SP
WHERE S.НОМЕР_ПОСТАВЩИКА = SP.НОМЕР_ПОСТАВЩИКА;
INSERT
INTO ВНЕШ_СОЕДИНЕНИЕ
310