Операторы обновления данных
В операции обновления данных входят три операции: операция удаления записей — ей соответствует оператор DELETE, операция добавления или ввода новых записей — ей соответствует оператор INSERT и операция изменения (обновления записей) — ей соответствует оператор UPDATE. Рассмотрим каждый из операторов подробнее.
Все операторы манипулирования данными позволяют изменить данные только в одной таблице.
Оператор ввода данных INSERT имеет следующий синтаксис:
INSERT INTO имя_таблицы [(<список столбцов>) ] VALUES (<список значений>)Подобный синтаксис позволяет ввести только одну строку в таблицу. Задание списка столбцов необязательно тогда, когда мы вводим строку с заданием значений всех столбцов. Например, введем новую книгу в таблицу BOOKS
INSERT INTO BOOKS ( ISBN,TITLE,AUTOR,COAUTOR,YEARIZD,PAGES) VALUES ("5-88782-290-2", "Аппаратные средства IBM PC. Энциклопедия", "Гук М. ","",2000,816)В этой книге только один автор, нет соавторов, но мы в списке столбцов задали столбец COAUTOR, поэтому мы должны были ввести соответствующее значение в разделе VALUES. Мы ввели пустую строку, потому что мы знаем точно, что нет соавтора. Мы могли бы ввести неопределенное значение NULL.
Так как мы вводим полную строку, то мы можем не задавать список столбцов, ограничиться только заданием перечня значений, в этом случае оператор ввода будет выглядеть следующим образом:
INSERT INTO BOOKS VALUES ("5-88782-290-2", "Аппаратные средства IBM PC. Энциклопедия", "Гук М.","",2000,816)Результаты работы обоих операторов одинаковые.
Наконец, мы можем ввести неполный перечень значений, то есть не вводить соавтора, так как он отсутствует для данного издания. Но в этом случае мы должны задать список вводимых столбцов, тогда оператор ввода будет выглядеть следующим образом:
INSERT INTO BOOKS ( ISBN,TITLE,AUTOR,YEARIZD,PAGES) VALUES ("5-88782-290-2", "Аппаратные средства IBM PC. Энциклопедия", "Гук М.",2000,816)Столбцу COAUTOR будет присвоено в этом случае значение NULL.
Какие столбцы должны быть заданы при вводе данных? Это определяется тем, как описаны эти столбцы при описании соответствующей таблицы. Если столбец или атрибут имеет признак обязательный (NOT NULL) при описании таблицы, то оператор INSERT должен обязательно содержать данные для ввода в каждую строку данного столбца. Поэтому если в таблице все столбцы обязательные, то каждая вводимая строка должна содержать полный перечень вводимых значений, а указание имен столбцов в этом случае необязательно. В противном случае, если имеется хотя бы один необязательный столбец и вы не вводите в него значений, задание списка имен столбцов — обязательно.
В набор значений могут быть включены специальные функции и выражения. Ограничением здесь является то, что значения этих функций должны быть определены на момент ввода данных. Поэтому, например, мы можем сформировать оператор ввода данных в таблицу EXEMPLAR следующим образом:
INSERT INTO EXEMPLAR (INV,ISBN,YES_NO,NUM_READER,DATE_IN, DATE_OUT) VALUES (1872, "5-88782-290-2",NO,344,GetDate(),DateAdd(d,GetDate(),14))И это означает, что мы выдали экземпляр книги с инвентарным номером 1872 читателю с номером читательского билете 344, отметив, что этот экземпляр не присутствует с этого момента в библиотеке, и определили дату выдачи книги как текущую дату (функция GetDate()), а дату возврата задали двумя неделями позднее, использовав при этом функцию DateAdd (), которая позволяет к одной дате добавить заданное количество интервалов даты и тем самым получить новое значение типа "дата". Мы добавили 14 дней к текущей дате.
Оператор ввода данных позволяет ввести сразу множество строк, если их можно выбрать из некоторой другой таблицы. Допустим, что у нас есть таблица со студентами и в ней указаны основные данные о студентах: их фамилии, адреса, домашние телефоны и даты рождения. Тогда мы можем сделать всех студентов читателями нашей библиотеки одним оператором:
INSERT INTO READER (NAME_READER, ADRESS, HOOM_PHONE, BIRTH_DAY)SELECT (NAME_STUDENT, ADRESS, HOOM_PHONE, BIRTH_DAY)FROM STUDENTПри этом номер читательского билета может назначаться автоматически, поэтому мы не вводим значения этого столбца в таблицу. Кроме того, мы предполагаем, что у студентов дневного отделения еще нет работы и поэтому нет рабочего телефона, и мы его не вводим.
Оператор удаления данных позволяет удалить одну или несколько строк из таблицы в соответствии с условиями, которые задаются для удаляемых строк.
Синтаксис оператора DELETE следующий:
DELETE FROM имя_таблицы [WHERE условия_отбора]Если условия отбора не задаются, то из таблицы удаляются все строки, однако это не означает, что удаляется вся таблица. Исходная таблица остается, но она остается пустой, незаполненной.
Например, если нам надо удалить результаты прошедшей сессии, то мы можем удалить все строки из отношения R1 командой
DELETE FROM R1Условия отбора в части WHERE имеют тот же вид, что и условия фильтрации в операторе SELECT. Эти условия определяют, какие строки из исходного отношения будут удалены. Например, если мы исключим студента Миронова А. В., то мы должны написать следующую команду:
DELETE FROM R2WHERE ФИО = 'Миронов А.В.'В части WHERE может находиться встроенный запрос. Например, если нам надо исключить неуспевающих студентов, то по закону о высшем образовании неуспевающим считается студент, имеющий две и более задолженности по последней сессии. Тогда нам в условиях отбора надо найти студентов, имеющих либо две или более двоек, либо два и более несданных экзамена из числа тех, которые студент сдавал. Для поиска таких горе-студентов нам надо выбрать из отношения R1 все строки с оценкой 2 или с неопределенным значением, потом надо сгруппировать полученный результат по атрибуту ФИО и, подсчитав количество строк в каждой группе, которое соответствует количеству несданных экзаменов каждым студентом, отобрать те группы, у которых количество строк не менее двух. Теперь попробуем просто записать эту сложную конструкцию на SQL и убедимся, что этот сложный запрос записывается достаточно компактно.
DELETE FROM R2 WHERE R2.ФИО IN (SELECT R1.ФИО FROM R1WHERE Оценка = 2 OR Оценка IS NULL GROUP BY R1.ФИО HAVING COUNT(*) >= 2Однако при выполнении операции DELETE, включающей сложный подзапрос, в подзапросе нельзя упоминать таблицу, из которой удаляются строки, поэтому СУБД отвергнет такой красивый подзапрос, который попытается удалить всех не только сдававших, но и несдававших студентов, которые имеют более двух задолженностей.
DELETE FROM R2 WHERE R2.ФИО IN (SELECT R1.ФИОFROM (R2 NATURAL INNER JOIN R3 ) LEFT JOIN R1 USING ( ФИО, Дисциплина)WHERE Оценка = 2 OR Оценка IS NULLGROUP BY R1.ФИОHAVING COUNT(*) >= 2Операция обновления данных UPDATE требуется тогда, когда происходят изменения во внешнем мире и их надо адекватно отразить в базе данных, так как надо всегда помнить, что база данных отражает некоторую предметную область. Например, в нашем учебном заведении произошло счастливое событие, которое связано с тем, что госпожа Степанова К. Е. пересдала экзамен по дисциплине "Базы данных" с двойки сразу на четверку. В этом случае нам надо срочно выполнить соответствующую корректировку таблицы R1. Операция обновления имеет следующий формат:
UPDATE имя_таблицыSET имя_столбца = новое_значение [WHERE условие_отбора]Часть WHERE является необязательной, так же как и в операторе DELETE. Она играет здесь ту же роль, что и в операторе DELETE, — позволяет отобрать строки, к которым будет применена операция модификации. Если условие отбора не задается, то операция модификации будет применена ко всем строкам таблицы.
Для решения ранее поставленной задачи нам необходимо выполнить следующую операцию
UPDATE R1SET R1.Оценка = 4WHERE R1.ФИО = "Степанова К.Е." AND R1.Дисциплина = "Базы данных"В каких случаях требуется провести изменение в нескольких строках? Это не такая уж редкая задача. Например, если мы расширим нашу учебную базу данных еще одним отношением, которое содержит перечень курсов, на которых учатся наши студенты, то можно с помощью операции обновления промоделировать операцию перевода групп на следующий курс. Пусть новое отношение R4 имеет следующую схему:
R4 = <Группа, Курс>R4 | |
Группа | Курс |
В этом случае перевод на следующий курс можно выполнить следующей операцией обновления:
UPDATE R4SET R4.Kypc = R4.Kypc + 1И результат будет выглядеть следующим образом:
Группа | Курс |
Операция модификации, так же как и операция удаления, может использовать сложные подзапросы. Расширим нашу базу еще одним отношением, которое будет содержать перечень студентов, получающих стипендию с указанием надбавки, которую они получают за отличную учебу. Исходно там могут находиться все студенты с указанием неопределенного размера стипендии. По мере анализа отношения R1мы можем постепенно заменять неопределенные значения на конкретные размеры стипендии. Отношение R5 имеет вид:
R5 | ||
ФИО | Группа | Стипендия |
Петров Ф. И. | <Null> | |
Сидоров К. А. | <Null> | |
Миронов А. В. | <Null> | |
Крылова Т. С. | <Null> | |
Владимиров В. А. | <Null> | |
Трофимов П. А. | <Null> | |
Иванова Е. А. | <Null> | |
Уткина Н. В. | <Null> |
Будем считать наличие трех пятерок по сессии признаком повышенной стипендии, + 50% к основной, наличие двух пятерок из сданных экзаменов и отсутствие двоек и троек на сданных экзаменах — признаком повышения стипендии на 25%, наличие хотя бы одной двойки среди сданных экзаменов — признаком снятия или отсутствия стипендии вообще, то есть –100% надбавки. При отсутствии троек на сданных экзаменах назначим обычную стипендию с надбавкой 0%. Однако все эти изменения мы должны будем сделать отдельными операциями обновления.
Назначение повышенной стипендии:
UPDATE R5SET R5.Стипендия = 50% WHERE R5.ФИО IN(SELECT R1.ФИОFROM R1WHERE R1.Оценка = 5GROUP BY R1.ФИОHAVING COUNT(*) =3 )Назначение стипендии с надбавкой 25%:
UPDATE R5SET R5.Стипендия = 25% WHERE R5.ФИО IN (SELECT R1.ФИО FROM R1WHERE R1.ФИО NOT IN (SELECT A.ФИО FROM R1 AWHERE A.Оценка <=3 OR A.Оценка IS NULL) GROUP BY R1.ФИО HAVING COUNT(*)>=2 )Назначение обычной стипендии:
UPDATE R5SET R5.Стипендия = 0%WHERE R5.ФИО IN (SELECT R1.ФИО FROM R1WHERE R1.Оценка >=4 AND R1.ФИО NOT IN (SELECT A.ФИО FROM R1 AWHERE A.Оценка <= 3 OR A.Оценка IS NULL) )Снятие стипендии:
UPDATE R5SET R5.Стипендия = —100% WHERE R5.ФИО IN(SELECT R1.ФИО FROM R1WHERE R1.Оценка <= 2 OR R1.Оценка IS NULL)