Оператор 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.

Пусть требуется указать «No PC» (нет ПК) в столбце type для тех моделей ПК из таблицы Product, для которых нет соответствующих строк в таблице PC. Решение посредством соединения таблиц можно записать так
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;

Рекомендуемые упражнения: 7, 9, 12, 15, 17, 20