Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Язык SQL выбор данных Ред 2010 12.01Зам.doc
Скачиваний:
11
Добавлен:
26.08.2019
Размер:
913.92 Кб
Скачать

Операторы манипулирования данными (dml) с подзапросами.

Все операции манипулирования данными связаны с понятием целостности базы данных - не все операторы манипулирования выполнимы.

В рассмотренных ранее операциях манипулирования данными DELETE, INSERT и UPDATE можно использовать подзапросы.

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

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

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

Пример: таблица со студентами (фамилии, адреса, домашние телефоны и даты рождения). Сделать всех студентов читателями библиотеки можно одним оператором:

INSERT INTO READER (NAME_READER, ADRESS, HOOM_PHONE, BIRTH_DAY)

SELECT (NAME_STUDENT, ADRESS, HOOM_PHONE, BIRTH_DAY)

FROM STUDENT

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

INSERT INTO Итог

(Название, Месяц, Стоимость )

SELECT Товар.Название, Month(Сделка.Дата)

AS Месяц, Sum(Товар.Цена*Сделка.Количество)

AS Стоимость

FROM Товар INNER JOIN Сделка

ON Товар.КодТовара= Сделка.КодТовара

GROUP BY Товар.Название, Month(Сделка.Дата)

Инструкция INSERT SELECT выполняется как атомарная операция, поэтому, если какая-то строка из-за ошибок не может быть добавлена в результирующую таблицу, в нее не вставляется ни одна строка.

В версии SQL Server 2005, если нужно создать виртуальную таблицу, основанную на значениях, нужно применять множественные инструкции SELECT, каждая из которых возвращает одну строку, основанную на значениях, а затем объединять строки с помощью операции Union all (это ограничение снято в SQL Server 2008).

Пример:

INSERT INTO dbo.Orders(orderid, orderdate, empid, custid)

SELECT 10007, '20090215', 2, 'B' UNION ALL

SELECT 10008, '20090215', 1, 'C' UNION ALL

SELECT 10009, '20090216', 2, 'C' UNION ALL

SELECT 10010, '20090216', 3, 'A';

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

Синтаксис оператора DELETE следующий:

DELETE FROM имя_таблицы [WHERE условия_отбора]

DELETE FROM имя_таблицы – удаляет все записи из таблицы.

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

Пример.

DELETE FROM R2

WHERE ФИО = 'Миронов А.В.'

Пример. Удалить все прошлогодние сделки.

DELETE

FROM Сделка

WHERE Year(Сделка.Дата)=Year(GETDATE())-1

Пример, надо исключить неуспевающих студентов (исходные отношения приведены ранее: база данных сдачи сессии в некотором учебном заведении из трех отношений R1 = (ФИО, Дисциплина, Оценка); R2 = (ФИО, Группа); R3 = (Группы, Дисциплина))

R1

ФИО

Дисциплина

Оценка

Петров Ф. И.

Базы данных

5

Сидоров К. А.

Базы данных

4

…………….

…………………..

….

Миронов А. В.

Теория информации

Null

…………….

…………………..

….

R2

ФИО

Группа

Петров Ф. И.

4906

Сидоров К. А.

4906

……………

……….

R3

Группа

Дисциплина

4906

Базы данных

4906

Теория информации

…….

…………………..

Для поиска надо выбрать из отношения R1 все строки с оценкой 2 или с неопределенным значением, потом надо сгруппировать полученный результат по атрибуту ФИО и, подсчитав количество строк в каждой группе, которое соответствует количеству несданных экзаменов каждым студентом, отобрать те группы, у которых количество строк не менее двух.

DELETE FROM R2 WHERE R2.ФИО IN (SELECT R1.ФИО FROM R1

WHERE Оценка = 2 OR Оценка IS NULL

GROOP BY R1.ФИО HAVING COUNT(*) >= 2

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

DELETE на основе соединения.

Поддерживается нестандартная запись операции DELETE на базе соединения. Соединение само служит задаче отбора, так как имеет фильтр, основанный на предикате (элемент ON).Соединение дает доступ к атрибутам связанных строк из другой таблицы, на которые можно ссылаться в элементе WHERE. Т.о. можно удалить строки из одной таблицы, основываясь на фильтре, использующем атрибуты из связанных строк другой таблицы.

Пример: удалить заказы, сделанные клиентами из США

DELETE FROM O

FROM dbo.Orders AS O

JOIN dbo.Customers AS C

ON O.custid = C.custid

WHERE C.country = N'USA';

Пример эквивалентного вложенного запроса:

DELETE FROM dbo.Orders

WHERE EXISTS

(SELECT *

FROM dbo.Customers AS C

WHERE Orders.custid = C.custid

AND C.country = N'USA');

Операция обновления данных UPDATE имеет следующий формат:

UPDATE имя_таблицы

SET имя_столбца = новое_значение [WHERE условие_отбора]

Оператор UPDATE позволяет изменить одну или несколько строк из таблицы в соответствии с условиями.

Часть WHERE является необязательной, так же как и в операторе DELETE. Она играет здесь ту же роль, что и в операторе DELETE, — позволяет отобрать строки, к которым будет применена операция модификации.

Если условие отбора не задается, то операция модификации будет применена ко всем строкам таблицы.

Пример: отношение R4 = <Группа, Курс>

R4

Группа

Курс

4906

3

4807

4

Перевод на следующий курс можно выполнить следующей операцией обновления:

UPDATE R4

SET R4.Kypc = R4.Kypc + 1

Результат:

Группа

Курс

4906

4

4807

5

Пример:

UPDATE R1

SET R1.Оценка = 4

WHERE R1.ФИО = "Степанова К.Е." AND R1.Дисциплина = "Базы данных"

Пример. Для товаров первого сорта установить цену в значение 140 и остаток – в значение 20 единиц.

UPDATE Товар SET Товар.Цена=140, Товар.Остаток=20

WHERE Товар.Сорт=" Первый "

Пример. Увеличить цену товаров первого сорта на 25%.

UPDATE Товар SET Товар.Цена=Товар.Цена*1.25

WHERE Товар.Сорт=" Первый "

Пример. В следующем примере столбец VacationHours в таблице Employee обновляется на 25% для 10 произвольных строк.

USE AdventureWorks;

GO

UPDATE TOP (10) HumanResources.Employee

SET VacationHours = VacationHours * 1.25 ;

GO

В части WHERE может находиться встроенный запрос.

Пример. В сделке с максимальным количеством товара увеличить число товаров на 10%.

UPDATE Сделка SET Сделка.Количество=

Сделка.Количество*1.1

WHERE Сделка.Количество=

(SELECT Max(Сделка.Количество) FROM Сделка)

Пример: Назначение повышенной стипендии.

Условие: наличие трех пятерок по сессии - повышение стипендии на 50%.

UPDATE R5

SET R5.Стипендия = 50% WHERE R5.ФИО IN

(SELECT R1.ФИО

FROM R1

WHERE R1.Оценка = 5

GROOP BY R1.ФИО

HAVING COUNT(*) =3 )

Условие: наличие двух пятерок из сданных экзаменов и отсутствие двоек и троек на сданных экзаменах — повышения стипендии на 25%,

UPDATE R5

SET R5.Стипендия = 25% WHERE R5.ФИО

IN (SELECT R1.ФИО FROM R1

WHERE R1.ФИО NOT

IN (SELECT A.ФИО FROM R1 A

WHERE A.Оценка <=3 OR A.Оценка IS NULL)

GROOP BY R1.ФИО HAVING COUNT(*)>=2 )

UPDATE на основе соединения.

Поддерживается запись операции UPDATE на базе соединения.

Пример: увеличить на 5% скидку на все товары заказов, сделанных клиентом 1.

UPDATE OD

SET discount = discount + 0.05

FROM dbo.OrderDetails AS OD

JOIN dbo.Orders AS O

ON OD.orderid = O.orderid

WHERE custid = 1;

Пример эквивалентного вложенного запроса:

UPDATE dbo.OrderDetails

SET discount = discount + 0.05

WHERE EXISTS

(SELECT * FROM dbo.Orders AS O

WHERE O.orderid = OrderDetails.orderid

AND custid = 1);

Пример: изменяется столбец SalesYTD в таблице SalesPerson для отображения самой последней информации о продажах, зафиксированной в таблице SalesOrderHeader.

USE AdventureWorks;

GO

UPDATE Sales.SalesPerson

SET SalesYTD = SalesYTD + SubTotal

FROM Sales.SalesPerson AS sp

JOIN Sales.SalesOrderHeader AS so

ON sp.SalesPersonID = so.SalesPersonID

AND so.OrderDate = (SELECT MAX(OrderDate)

FROM Sales.SalesOrderHeader

WHERE SalesPersonID =

sp.SalesPersonID);

GO

Пример: В предыдущем примере подразумевается, что на конкретного менеджера по продажам на каждую конкретную дату записана только одна продажа.

В ситуации, когда один менеджер может зарегистрировать за один день несколько продаж, все продажи одного менеджера должны объединяться внутри инструкции UPDATE, как показано в следующем примере:

USE AdventureWorks;

GO

UPDATE Sales.SalesPerson

SET SalesYTD = SalesYTD +

(SELECT SUM(so.SubTotal)

FROM Sales.SalesOrderHeader AS so

WHERE so.OrderDate = (SELECT MAX(OrderDate)

FROM Sales.SalesOrderHeader AS so2

WHERE so2.SalesPersonID =

so.SalesPersonID)

AND Sales.SalesPerson.SalesPersonID = so.SalesPersonID

GROUP BY so.SalesPersonID);

GO