Оператор UPDATE
Оператор UPDATE изменяет имеющиеся данные в таблице. Команда имеет следующий синтаксис:
UPDATE <имя таблицы>
SET {<имя столбца> = {<выражение для вычисления значения столбца>
| NULL
| DEFAULT},...}
[ {WHERE <предикат>}]
С помощью одного оператора могут быть заданы значения для любого количества столбцов. Однако в одном и том же операторе UPDATE можно вносить изменения в каждый столбец указанной таблицы только один раз. При отсутствии предложения WHERE будут обновлены все строки таблицы.
Если столбец допускает NULL-значение, то его можно указать в явном виде. Кроме того, можно заменить имеющееся значение на значение по умолчанию (DEFAULT) для данного столбца.
Ссылка на «выражение для вычисления значения столбца» может относиться к текущим значениям в изменяемой таблице. Например, мы можем уменьшить все цены портативных компьютеров на 10 процентов с помощью следующего оператора:
UPDATE Laptop
SET price = price*0.9;
Разрешается также значения одних столбцов присваивать другим столбцам. Пусть, например, требуется заменить жесткие диски менее 10 Гбайт в портативных компьютерах. При этом емкость новых дисков должна составлять половину объема RAM, имеющейся в данных устройствах. Эту задачу можно решить следующим образом:
UPDATE Laptop
SET hd = ram/2 WHERE hd < 10;
Естественно, типы данных столбцов hd и ram должны быть совместимы. Для приведения типов может использоваться выражение CAST (пункт 5.9).
Если требуется изменять данные в зависимости от содержимого некоторого столбца, можно воспользоваться выражением CASE (пункт 5.9) Если, скажем, нужно поставить жесткие диски объемом 20 Гбайт на портативные компьютеры с памятью менее 128 Мбайт и 40 гигабайтные — на остальные портативные компьютеры, то можно написать такой запрос:
UPDATE Laptop
SET hd = CASE
WHEN ram < 128
THEN 20
ELSE 40
END;
Для вычисления значений столбцов допускается также использование подзапросов. Например, требуется укомплектовать все портативные компьютеры самыми быстрыми процессорами из имеющихся в наличии. Тогда можно написать:
UPDATE Laptop
SET speed = (SELECT MAX(speed)
FROM Laptop
);
Необходимо сказать несколько слов об автоинкрементируемых столбцах. Если столбец code в таблице Laptop определен как IDENTITY(1,1), то следующий оператор
UPDATE Laptop
SET code = 5
WHERE code = 4;
не будет выполнен, так как автоикрементируемое поле не допускает обновления, и мы получим соответствующее сообщение об ошибке. Чтобы выполнить все же эту задачу, можно поступить следующим образом. Сначала вставить нужную строку, используя SET IDENTITY_INSERT, после чего удалить старую строку:
SET IDENTITY_INSERT Laptop_ID ON;
INSERT INTO Laptop_ID(code, model, speed, ram, hd, price, screen)
SELECT 5, model, speed, ram, hd, price, screen
FROM Laptop_ID WHERE code = 4;
DELETE FROM Laptop_ID
WHERE code = 4;
Разумеется, другой строки со значением code = 5 в таблице быть не должно.
В Transact-SQL оператор UPDATE расширяет стандарт за счет применения необязательного предложения FROM. В этом предложении специфицируется таблица, обеспечивающая критерий для операции обновления. Дополнительную гибкость здесь дают операции соединения таблиц.
Пример 6.2.1.
UPDATE Product
SET type = 'No PC'
FROM Product pr LEFT JOIN
PC on pr.model=PC.model
WHERE type = 'pc' AND
PC.model IS NULL;
Здесь применяется внешнее соединение, в результате чего столбец PC.model для моделей ПК, отсутствующих в таблице PC, будет содержать NULL-значение, что и используется для идентификации подлежащих обновлению строк. Естественно, эта задача имеет решение и в «стандартном» исполнении:
UPDATE Product
SET type = 'No PC'
WHERE type = 'pc' AND
model NOT IN (SELECT model
FROM PC
);
MySQL
Оператор UPDATE в MySQL также имеет функциональность, аналогичную дополнительному предложению FROM в SQL Server. Только вместо FROM соединение таблиц выполняется непосредственно в предложении UPDATE. Пример 6.1.2 в синтаксисе MySQL можно переписать следующим образом
UPDATE Product pr
LEFT JOIN PC ON pr.model=PC.model
SET type = 'No PC'
WHERE type = 'pc'
AND PC.model IS NULL;