SQL-Ex blog
Оператор UPDATE позволяет изменять значения в таблицах базы данных, включая временные таблицы. С помощью единственного оператора вы можете обновить одну или более строк, один или более столбцов, или любую их комбинацию. Вы можете даже обновить несколько таблиц. Проработав эту статью вы узнаете, что оператор UPDATE прост и интуитивно понятен, если усвоить основы его работы.
Подготовка среды MySQL
Для примеров этой статьи я использовал ту же самую базу данных (travel) и таблицы (manufacturers и airplanes), которые применялись в нескольких последних статьях этой серии.
Замечание. Примеры предполагают, что вы проработали предыдущую статью. В этом случае база данных travel уже должна быть установлена и готова для работы. Если нет, вы также можете использовать примеры данной статьи, только имейте в виду, что результаты ваших запросов могут несколько отличаться от приведенных здесь.
Для установки базы данных travel — если вы этого еще не сделали — загрузите файл MySQL_06_setup.sql и выполните скрипт SQL на экземпляре MySQL. Скрипт создает базу данных, таблицы и вставляет в них тестовые данные. В качестве альтернативы, вы можете создать базу данных, а затем выполнить следующий скрипт для создания таблиц manufacturers и airplanes:
CREATE TABLE manufacturers (
manufacturer_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
manufacturer VARCHAR(50) NOT NULL,
create_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
last_update TIMESTAMP NOT NULL
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (manufacturer_id) )
ENGINE=InnoDB AUTO_INCREMENT=1001;
CREATE TABLE airplanes (
plane_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
plane VARCHAR(50) NOT NULL,
manufacturer_id INT UNSIGNED NOT NULL,
engine_type VARCHAR(50) NOT NULL,
engine_count TINYINT NOT NULL,
max_weight MEDIUMINT UNSIGNED NOT NULL,
wingspan DECIMAL(5,2) NOT NULL,
plane_length DECIMAL(5,2) NOT NULL,
parking_area INT GENERATED ALWAYS
AS ((wingspan * plane_length)) STORED,
icao_code CHAR(4) NOT NULL,
create_date TIMESTAMP NOT NULL
DEFAULT CURRENT_TIMESTAMP,
last_update TIMESTAMP NOT NULL
DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (plane_id),
CONSTRAINT fk_manufacturer_id
FOREIGN KEY (manufacturer_id)
REFERENCES manufacturers (manufacturer_id) )
ENGINE=InnoDB AUTO_INCREMENT=101;
Затем вам нужно добавить данные в таблицы manufacturers и airplanes для поддержки примеров в этой статье. Начните с таблицы manufacturers, выполнив следующий оператор INSERT, который добавит производителя Beagle Aircraft Limited:
INSERT INTO manufacturers (manufacturer)
VALUES ('Beagle Aircraft Limited');
SELECT manufacturer_id
FROM manufacturers
WHERE manufacturer = 'Beagle Aircraft Limited';
После вставки данных оператор SELECT возвращает вновь добавленное значение из столбца manufacturer_id. Если вы следовали в точности последней паре статей, то значение будет равно 1008. Если нет, отметьте для себя значение manufacturer_id, которое вы получите, поскольку оно вам понадобится далее в статье, начиная со следующего оператора INSERT:
INSERT INTO airplanes
(plane, manufacturer_id, engine_type, engine_count,
wingspan, plane_length, max_weight, icao_code)
VALUES
('A.61 Terrier',1008,'piston',1,36,23.25,2400,'AUS6'),
('B.121 Pup',1008,'piston',1,31,23.17,1600,'PUP'),
('B.206',1008,'piston',2,55,33.67,7500,'BASS'),
('D.4-108',1008,'piston',1,36,23.33,1900,'D4'),
('D.5-108 Husky',1008,'piston',1,36,23.17,2400,'D5');
Если необходимо, замените значение 1008 на ваше значение manufacturer_id и выполните этот оператор. Сделав это, вы должны быть готовы следовать примерам из данной статьи. Однако имейте в виду, что ряд следующих примеров ссылается на столбец Manufacturer_id, поэтому, если значение в вашей системе не равно 1008, обязательно используйте правильное значение.
Синтаксис оператора UPDATE
Оператор UPDATE в MySQL поддерживает 5 предложений, два из которых являются обязательными, а три — необязательными, что отмечено в следующем синтаксисе:
UPDATE [IGNORE] table_name
SET column = value [, column = value].
[WHERE where_condition]
[ORDER BY order_list]
[LIMIT row_count]
- Предложение UPDATE, одно из двух обязательных предложений, задает таблицу, которая является целью обновления. Вы можете указать несколько таблиц в этом предложении, разделив их запятыми, но я в этой статье сфокусируюсь на обновлениях одной таблицы. Я оставлю тему обновления нескольких таблиц для более продвинутых статей.
- Предложение SET, другое обязательное предложение, определяет обновляемые столбцы. Вы можете включить задания для одного или более столбцов. Для каждого задания указывается имя столбца, знак равенства и новое значение. Если включены несколько заданий, разделяйте их запятыми.
- Предложение WHERE определяет подлежащие обновлению строки на основе одного или нескольких условий. Предложение работает во многом подобно предложению WHERE в операторе SELECT. Хотя предложение WHERE не является обязательным, вам следует очень внимательно выполнять оператор UPDATE, который не включает это предложение. Без него оператор обновит каждую строку таблицы, если не включено предложение LIMIT.
- Предложение ORDER BY задает порядок, в котором должны обновляться строки. Это может использоваться в ситуациях, которые в противном случае могут привести к ошибке, как вы увидите далее в статье. Предложение ORDER BY подобно аналогичному предложению в операторе SELECT. Это предложение не может использоваться для обновления нескольких таблиц.
- Предложение LIMIT ограничивает число строк, которые будут обновляться. Если включено предложение WHERE, количество применяется к строкам, возвращаемым этим предложением. Это означает, что оператор оперирует теми строками, которые удовлетворяют условиям WHERE, вне зависимости от того, были ли эти строки фактически обновлены. Как и в случае предложения ORDER BY, предложение LIMIT не может использоваться для обновления нескольких таблиц.
Когда вы увидите этот оператор в действии, у вас не должно возникнуть проблем с пониманием того, как эти предложения работают, и использованием их для обновления данных. На самом деле, обновлять данные очень просто, но если вы не будете осторожны, можно натворить много бед. Модификацию данных может оказаться сложно отменить, поэтому необходимо действовать осторожно, особенно когда вы только начали изучение оператора UPDATE. Конечно, не следует практиковаться в производственной базе. Если вы выполняете обновление в производственной среде, убедитесь, что вы делаете это в рамках транзакции, о чем я собираюсь рассказать далее в этой серии.
Выполнение базового обновления в MySQL
Пора посмотреть оператор UPDATE в действии, чтобы вы почувствовали, как он работает. Как я уже говорил, только предложения UPDATE и SET являются обязательными, поэтому с них и начнем.
Предположим, что вы хотите округлить все значения в столбце wingspan таблицы airplanes до целых чисел. Чтобы добиться этого, создадим следующий оператор UPDATE:
UPDATE airplanes
SET wingspan = ROUND(wingspan);
Предложение UPDATE задает airplanes в качестве целевой таблицы, а предложение SET указывает, что значения в столбце wingspan должны округляться, что достигается при использовании встроенной функции ROUND.
Это все, что требуется для обновления данных wingspan. Однако есть большая вероятность, что при попытке запустить этот оператор вы получите следующую ошибку:
Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. To disable safe mode, toggle the option in Preferences -> SQL Editor and reconnect.
(Вы используете безопасный режим обновления пытались обновить таблицу без предложения WHERE, которое использует КЛЮЧЕВОЙ столбец. Для отключения безопасного режима переключите опцию в Preferences -> SQL Editor и соединитесь повторно.)
По умолчанию вы не можете выполнить обновление без предложения WHERE, которое задает ключевой столбец. Это помогает гарантировать, что вы не внесете радикальные изменения, о которых потом будете жалеть. Вы можете отключить безопасный режим (как предлагается в сообщении об ошибке) либо на постоянной основе, либо временно. Я рекомендую это делать временно, чтобы избежать нежелательных изменений когда-либо впоследствии.
Для временного отключения безопасного режима используйте оператор SET для установки системной переменной SQL_SAFE_UPDATES в значение 0 до выполнения оператора UPDATE, а затем установки переменной в 1 после выполнения оператора, как показано в следующем примере:
SET SQL_SAFE_UPDATES = 0;
UPDATE airplanes
SET wingspan = ROUND(wingspan);
SET SQL_SAFE_UPDATES = 1;
Операторы SET просто переключают переменную во время текущей сессии. Однако имейте в виду, что оператор SET поддерживает опцию GLOBAL, которая устанавливает переменную на глобальном уровне. Возьмите за правило не использовать этот параметр при отключении безопасных обновлений. Гораздо менее рискованно использовать этот тип изменений на уровне сессии, чтобы избежать незапланированных несчастных случаев. Используйте GLOBAL, только если это важно в ваших обстоятельствах.
Более подробно о SET, глобальных переменных и настройках читайте в документации MySQL.
Даже на сессионном уровне оператор SET делает возможным выполнение оператора UPDATE без генерации ошибки. Подтвердить изменения после выполнения скрипта выше можно с помощью простого оператора SELECT:
SELECT * FROM airplanes;
На рисунке 1 показаны результаты, возвращаемые оператором SELECT. Обратите внимание, что значения wingspan теперь являются целыми числами.

Рис.1. Округление значений в столбце wingspan
В некоторых случаях вам может потребоваться обновить несколько столбцов одновременно. Для этого вам нужно добавить задания для этих столбцов, разделяя их запятыми. Например, следующий оператор UPDATE модифицирует оба столбца wingspan и plane_length:
SET SQL_SAFE_UPDATES = 0;
UPDATE airplanes
SET wingspan = ROUND(wingspan), plane_length = ROUND(plane_length);
SET SQL_SAFE_UPDATES = 1;
Задания для обоих столбцов работают одинаково. Вы просто округляете значения столбца до целых чисел. Если запросить таблицу airplanes после выполнения оператора UPDATE, ваши результаты должны выглядеть подобно показанным на рис.2.

Рис.2. Округление значений в столбцах wingspan и plane_length
Используя предложения UPDATE и SET, вы можете быстро обновить все значения столбца. Просто будьте осторожны, если используете этот подход. Слишком легко все испортить.
Добавление предложения WHERE в оператор UPDATE
Большинство ваших операторов UPDATE будут, вероятно, включать предложение WHERE, чтобы помочь вам лучше определить данные, подлежащие изменению. Предложение WHERE задает одно или более условий, которые сужают объем обновляемых строк. Например, следующий оператор включает предложение WHERE, которое ограничивает обновляемые строки значением 1008 в столбце manufacturer_id:
UPDATE airplanes
SET engine_type = 'piston (adg-i)'
WHERE manufacturer_id = 1008;
SELECT *
FROM airplanes
WHERE manufacturer_id = 1008;
Предложение SET в этом операторе устанавливает engine_type в значение «piston (adg-i)» для целевых строк. Результаты выполнения оператора должны выглядеть как на рис.3.

Рис.3. Ограничение обновления заданными строками
Замечание: Если вам интересно, значение adg-i — это ссылка на классификацию Airplane Design Group (ADG), систему, используемую для классификации самолетов, подразделяя их на шесть групп на базе размаха крыльев и высоты хвоста. i в нижнем регистре означает, что самолеты в этом примере относятся к Группе I. (Я понимаю, что вы, вероятно, захотите добавть столбец для групп ADG. Подход, который я использовал здесь, предназначался только для демонстрации этих концепций.)
Таким образом, оказывается, что аэроплан B.206 должен фактически быть в Группе II, и значит нам нужно обновить эту запись без обновления остальных. К счастью, вы можете определять несколько условий в предложении WHERE, чтобы сократить число строк. В следующем примере предложение WHERE включает два условия, одно для столбца manufacturer_id, а другое — для столбца plane.
UPDATE airplanes
SET engine_type = 'piston (adg-ii)'
WHERE manufacturer_id = 1008 AND plane = 'B.206';
Как в предыдущем примере, предложение WHERE ограничивает обновление строками, для которых значение manufacturer_id равно 1008. Однако это предложение также указывает, что значение plane должно равняться B.206. Два условия связываются логическим оператором AND, который означает, что оба условия должны быть истинны для обновляемых строк.
После выполнения оператора UPDATE вы можете опять вывести эти строки. Ваши результаты должны быть похожи на представленные на рис.4. Обратите внимание, что самолет B.206 теперь представлен в группе Group II.

Рис.4. Ограничение обновления одной заданной строкой
Вы можете сделать предложение WHERE настолько детальным, чтобы гарантировать обновление целевых строк и никаких больше. Для этого используйте ваши логические операторы корректно, чтобы гарантировать точную логику условных выражений.
Работа с значениями столбца
В первом примере этой статьи вы видели, как использовать системную функцю ROUND для округления значений в таблице airplanes. Когда вы обновляете столбец этим способом, MySQL использует текущее значение для создания нового значения. Способность использовать текущее значение делает возможным построить на этом значении новое способами, выходящими за пределы простого применения функции. Например, следующий оператор UPDATE добавит 3 к значению wingspan и 5 к значению plane_length:
UPDATE airplanes
SET wingspan = wingspan + 3, plane_length = plane_length + 5
WHERE plane_id = 344;
В этом случае я использовал значение plane_id = 344 в предложении WHERE, которое мне пришлось искать в таблице. Однако вы могли бы использовать другой метод для нахождения этого значения, например, выбрать его с помощью подзапроса, что я планирую рассмотреть далее в этой серии.
После выполнения этого оператора вы можете выполнить запрос к таблице airplanes для проверки результатов, которые должны быть похожи на представленные на рис.5.

Рис.5. Увеличение значений в столбцах wingspan и plane_length
Если вы сравните рисунки 5 и 4, то увидите, что строка со значением plane_id = 344 была обновлена. Вы можете также заметить, что MySQL автоматически обновила столбец parking_area, который является генерируемым столбцом, перемножающим значения wingspan и plane_length.
Если вы попытаетесь обновить столбец на то же самое значение, которое уже есть, MySQL окажется достаточно умен, чтобы понять это и не менять исходное значение. Такой подход может потенциально уменьшить бесполезную нагрузку и минимизировать воздействие на конкурирующие операции, которые могут пытаться извлечь или модифицировать это значение в то же самое время. MySQL также понимает, когда вы пытаетесь вставить неприемлемое значение в столбец. Например, следующий оператор UPDATE пытается изменить значение столбца engine_type на NULL:
UPDATE airplanes SET engine_type = NULL WHERE plane_id = 344;
Поскольку столбец определен как NOT NULL, оператор UPDATE потерпит неудачу и сгенерирует следующую ошибку:
Error Code: 1048. Column ‘engine_type’ cannot be null
(столбец ‘engine_type’ не может быть null)
Вы также получите ошибку, если попытаетесь обновить столбец значением некорректного типа данных. Например, следующий оператор UPDATE пытается обновить столбец max_weight на строковое значение unknown:
UPDATE airplanes
SET max_weight = 'unknown'
WHERE plane_id = 344;
Неудивительно, что этот оператор также не будет выполнен, поскольку столбец max_weight определен с типом данных MEDIUMINT. Вместо обновления MySQL вернет следующую ошибку:
Error Code: 1366. Incorrect integer value: ‘unknown’ for column ‘max_weight’ at row 1
(Некорректное целое значение: ‘unknown’ для столбца ‘max_weight’ в строке 1)
Как и в случае вставки данных, для обновления данных вам следует иметь информацию о целевых столбцах, которые вы пытаетесь обновить. Недостаточно знать только тип данных. Вы должны также понимать, как определен тип данных. Например, если вы попытаетесь обновить столбец icao_code строкой abcdef, будет генерироваться ошибка, поскольку столбец определен как CHAR(4).
Обновление столбцов внешнего ключа в таблицах MySQL
У вас может появиться желание обновить значение в столбце внешнего ключа. Однако это может оказаться непросто, поскольку MySQL выполняет проверки внешнего ключа. Например, предположим, что вы хотите обновить столбец manufacturer_id в таблице airplanes:
UPDATE airplanes
SET manufacturer_id = 2001
WHERE manufacturer_id = 1008;
Неудивительно, что MySQL заблокирует вашу попытку выполнить этот оператор и вернет вместо этого следующую ошибку (если вы не добавили ключевое слово IGNORE):
Error Code: 1452. Cannot add or update a child row: a foreign key constraint fails (`travel`.`airplanes`, CONSTRAINT `fk_manufacturer_id` FOREIGN KEY (`manufacturer_id`) REFERENCES `manufacturers` (`manufacturer_id`))
(Невозможно добавить или изменить дочернюю строку: нарушение ограничения внешнего ключа)
Вы не можете обновить внешний ключ значением, которого не существует в ссылочном столбце. Вы должны сначала внести необходимые изменения в родительскую таблицу. Однако это тоже может оказаться затруднительным. Например, вы могли бы попытаться обновить значение manufacturer_id в таблице manufacturers:
UPDATE manufacturers
SET manufacturer_id = 2001
WHERE manufacturer_id = 1008;
К сожалению, это приведет к тому, что MySQL опять сгенерирует ошибку, поскольку вы не можете обновить значение, на которое ссылается внешний ключ:
Error Code: 1451. Cannot delete or update a parent row: a foreign key constraint fails (`travel`.`airplanes`, CONSTRAINT `fk_manufacturer_id` FOREIGN KEY (`manufacturer_id`) REFERENCES `manufacturers` (`manufacturer_id`))
(Нельзя удалить или обновить родительскую строку: нарушено ограничение внешнего ключа.)
Вы можете обойти эти проблемы, временно отключив проверки внешнего ключа в пределах сессии (или установив опцию CASCADE для внешнего ключа, о чем я буду говорить в последующей статье). Для этого установите системную переменную foreign_key_checks в значение 0 перед выполнением оператора UPDATE, а затем установите ее обратно в значение 1 после выполнения операторов:
SET foreign_key_checks = 0;
UPDATE manufacturers
SET manufacturer_id = 2001
WHERE manufacturer_id = 1008;
UPDATE airplanes
SET manufacturer_id = 2001
WHERE manufacturer_id = 1008;
SET foreign_key_checks = 1;
Таким образом вы можете обновить значения manufacturer_id в обеих таблицах без возникновения ошибок внешнего ключа. В качестве напоминания скажу, избегайте использования опции GLOBAL в ваших операторах SET. Если выключить проверки внешнего ключа на глобальном уровне, вы рискуете нарушить целостность ваших данных.
После выполнения этих операторов вы можете сделать запрос к таблице manufacturers, чтобы проверить выполненные изменения:
SELECT * FROM manufacturers WHERE manufacturer_id = 2001;
На рисунке 6 показаны данные, возвращаемые этим оператором. Как видно, таблица была обновлена без проблем, в частности, потому что вы задали новое значение первичного ключа, которого еще не существовало.

Рис.6. Обновление таблицы manufacturers
Вы можете также запросить таблцу airplanes, чтобы проверить, что строки были правильно обновлены:
SELECT * FROM airplanes WHERE manufacturer_id = 2001;
На рисунке 7 показаны результаты, возвращаемые запросом. Как и ожидалось, значения manufacturer_id были обновлены для всех целевых строк.

Рис.7. Обновление столбца manufacturer_id в таблице airplanes
Вероятно, вам не придется обновлять столбцы внешнего ключа слишком часто, но важно понимать, во что это выливается, если случится. Просто знайте, что имеются и другие проблемы, о которых стоит беспокоиться, например, не пытаться вставить повторяющиеся значения первичных ключей.
Обновление столбцов первичного ключа в таблицах MySQL
Как и в случае внешних ключей, вам может иногда понадобиться обновить значения в столбце первичного ключа. Если вы обновляете единственное значение (как в случае выше), то обычно проблем не возникает, коль скоро новое значение удовлетворяет требованиям столбца. Однако все становится сложнее, если одновременно обновляются несколько значений. Например, следующий оператор UPDATE пытается добавить 1 ко всем значениям plane_id в строках, для которых значение manufacturer_id равно 2001:
UPDATE airplanes
SET plane_id = plane_id + 1
WHERE manufacturer_id = 2001;
Оператор имеет хороший шанс завершиться неудачно из-за порядка, в котором MySQL обновляет каждую строку данных (поскольку вы не можете делать никаких предположений о порядке, который ядро базы данных выберет при обновлении данных). Это связано с тем, что MySQL пытается обновить исходное значение на значение, которое уже существует и само ожидает обновления. Например, если MySQL пытается обновить первую строку с 342 на 343 перед обновлением второй строки, то оператор завершится неудачно, и MySQL вернет следующую ошибку:
Error Code: 1062. Duplicate entry ‘343’ for key ‘airplanes.PRIMARY’
(дубликат записи 343 для ключа ‘airplanes.PRIMARY’)
У вас может возникнуть соблазн включить ключевое слово IGNORE, чтобы попытаться обойти эту проблему:
UPDATE IGNORE airplanes
SET plane_id = plane_id + 1
WHERE manufacturer_id = 2001;
Ключевое слово IGNORE дает указание MySQL вернуть предупреждение, а не ошибку, и продолжить, а не остановить, выполнение оператора. В этом случае вы, вероятно, получите четыре предупреждения и сообщение, что одна строка была успешно обновлена:
1 row(s) affected, 4 warning(s):
1062 Duplicate entry ‘343’ for key ‘airplanes.PRIMARY’
1062 Duplicate entry ‘344’ for key ‘airplanes.PRIMARY’
1062 Duplicate entry ‘345’ for key ‘airplanes.PRIMARY’
1062 Duplicate entry ‘346’ for key ‘airplanes.PRIMARY’
Rows matched: 5 Changed: 1 Warnings: 4
Если обратиться к таблице airplanes, то можно увидеть, что только последняя строка была обновлена, что видно на рисунке 8. Это объясняется тем, что только последняя строка не пыталась обновить первичный ключ существующим значением.

Рис.8. Использование опции IGNORE при обновлении столбца plane_id
Лучшим решением будет включить предложение ORDER BY, которое сортирует строки по значениям plane_id в убывающем порядке:
UPDATE airplanes
SET plane_id = plane_id + 1
WHERE manufacturer_id = 2001
ORDER BY plane_id DESC;
Когда вы включаете ORDER BY таким образом, MySQL применяет обновление, начиная с последней строки, позволяя инкрементировать значения на 1 без возникновения ошибок или предупреждений.
На рисунке 9 показаны данные после выполнения оператора UPDATE.

Рис.9. Добавление предложения ORDER BY в оператор UPDATE
Вероятно, вам не очень часто потребуется использовать предложение ORDER BY, но это может оказаться весьма полезным.
В этом смысле похоже ведет себя другое предложение — LIMIT, — которое ограничивает число обновляемых строк. Например, следующий оператор обновления ограничивает число строк значением 3:
UPDATE airplanes
SET plane_id = plane_id + 1
WHERE manufacturer_id = 2001
ORDER BY plane_id DESC
LIMIT 3;
Поскольку оператор UPDATE также содержит предложение ORDER BY, три обновляемых строк следуют снизу вверх. На рисунке 10 показаны результаты запроса к таблице после обновления.

Рис.10. Добавление предложения LIMIT в оператор UPDATE
Я полагаю, что вы не очень часто будете включать предложение LIMIT в операторы UPDATE (если вообще будете), но могут возникнуть ситуации, когда вы сочтете это полезным. Например, вы захотите протестировать оператор UPDATE, который предположительно должен модифицировать большое число строк. Включение предложения LIMIT во время тестирования оператора сократит время на обработку, чтобы проверить правильность работы оператора.
Работа с оператором UPDATE в MySQL
Оператор UPDATE является одним из наиболее часто используемых при работе с даными в MySQL. В большинстве случаев вы ограничитесь предложениями UPDATE, SET и WHERE. Иногда вы можете отказаться от предложения WHERE — на свой страх и риск — а иногда вы можете сочетать его с предложением ORDER BY или LIMIT (или обоми). Однако основная масса ваших обновлений, вероятно, будет ограничиваться тремя основными предложениями.
Независимо от используемых предложений вам нужно понимать, как они работают, чтобы гарантировать наиболее эффективную модификацию данных при точности обновления. К счастью, оператор UPDATE довольно прост для понимания, поэтому у вас не должно возникнуть проблем с его применением.
Как использовать оператор UPDATE в SQL: примеры для разных СУБД

В этой статье мы рассмотрим оператор SQL UPDATE и покажем, как его применять. Также мы посмотрим на некоторые отличия в синтаксисе этого оператора в разных версиях SQL разных систем управления реляционными базами данных (СУРБД).
Курс Стратегический маркетинг.
Від хаосу до системного маркетингу разом із Тетяною Лукинюк, B2C-директором у Kyivstar, колишнім CMO у Coca-Cola, Mars Ukraine та генеральною директоркою у Red Bull Ukraine.
Больше про работу с SQL для аналитики данных можно узнать на курсе Junior Data Analyst от robot_dreams.
Что такое оператор SQL UPDATE

Оператор UPDATE — один из основных операторов языка управления данными DML Data Manipulation Language — это подмножество SQL. наряду с SELECT , DELETE и INSERT .
Назначение и сферы применения
Оператор UPDATE используется для изменения строк в таблице базы данных. С его помощью можно изменять данные в одном или нескольких столбцах и выбирать для этого:
Курс Англійської.
Вивчай англійську прямо зі свого смартфона за допомоги смарт-платформи.
Оператор может быть полезен для таких бизнес-задач, как обновление статуса заказа, изменение этапа доставки, смена адреса клиента, увеличение заработной платы сотрудника и т.п.
Синтаксис UPDATE
Базовый синтаксис оператора UPDATE с использованием оператора условий WHERE выглядит так:
UPDATE имя_таблицы SET столбец1 = значение1, столбец2 = значение2, . столбецN = значениеN [WHERE условие];
Аргументы/параметры
Чтобы использовать оператор UPDATE , нужно указать для него такие параметры:
- имя_таблицы — имя таблицы, в которой планируются изменения;
- столбец1 … столбецN — имена столбцов, в которых нужно изменить значения;
- значение1 … значениеN — значения, которые нужно вставить вместо прежних значений в указанные столбцы.
Также после WHERE можно записать условие для выбора строк. Если WHERE не использовать, обновятся все строки в таблице.
Курс Python basic.
Після курсу ви зможете впевнено працювати з чатботами, скриптами, вбудованими системами, веб- та мобільними застосунками, а також навіть ігровими програмами.
Совместимость
Разработчики СУБД выпускают свои диалекты SQL, которые расширяют стандартный SQL и немного отличаются, как от него, так и друг от друга.
Например, чтобы ограничить количество изменяемых строк определенным числом или процентом, в T-SQL в операторе UPDATE используется оператор TOP , в MySQL — LIMIT , в Oracle и PostgreSQL — FETCH (см. Пример 4 в конце статьи).
Отличий в диалектах SQL на самом деле гораздо больше. Чтобы изучить их углубленно, приходите на курс Junior Data Analyst от robot_dreams. Он стартует уже 27 марта.
Рассмотрим синтаксис UPDATE подробнее в таких диалектах SQL:
- Transact-SQL (T-SQL);
- MySQL;
- PostgreSQL;
- Oracle Database.
Transact-SQL (T-SQL)


Transact-SQL (T-SQL) — это проприетарное частное расширение языка SQL, созданное компанией Microsoft для использования в Microsoft SQL Server. T-SQL поддерживается в Microsoft Azure SQL Database и совместим с СУБД Sybase.
Курс Python.
Цю мову програмування використовують від базових концепцій до складних застосувань у сферах штучного інтелекту. Після проходження курсу гарантовано отримай роботу в ІТ.
Ниже приведен синтаксис UPDATE , используемый в T-SQL:
— Syntax for SQL Server and Azure SQL Database [ WITH [. n] ] UPDATE [ TOP ( expression ) [ PERCENT ] ] < < table_alias | | rowset_function_limited [ WITH ( [ . n ] ) ] > | @table_variable > SET < column_name = < expression | DEFAULT | NULL >| < udt_column_name.< < property_name = expression | field_name = expression >| method_name ( argument [ . n ] ) > > | column_name < .WRITE ( expression , @Offset , @Length ) >| @variable = expression | @variable = column = expression | column_name < += | -= | *= | /= | %= | &= | ^= | |= >expression | @variable < += | -= | *= | /= | %= | &= | ^= | |= >expression | @variable = column < += | -= | *= | /= | %= | &= | ^= | |= >expression > [ . n ] [ ] [ FROM < > [ . n ] ] [ WHERE < | < [ CURRENT OF < < [ GLOBAL ] cursor_name >| cursor_variable_name > ] > > ] [ OPTION ( [ . n ] ) ] [ ; ] ::=
MySQL
MySQL — это свободная СУРБД с открытым исходным кодом, созданная компанией MySQL AB.
Ниже приведен синтаксис UPDATE , используемый в MySQL.
Синтаксис для одной таблицы:
UPDATE [LOW_PRIORITY] [IGNORE] table_reference SET assignment_list [WHERE where_condition] [ORDER BY . ] [LIMIT row_count] value: assignment: col_name = value assignment_list: assignment [, assignment]
Синтаксис для нескольких таблиц:
UPDATE [LOW_PRIORITY] [IGNORE] table_references SET assignment_list [WHERE where_condition]
PostgreSQL
PostgreSQL — это объектно-реляционная СУБД, которая поддерживает как реляционные (SQL), так и нереляционные запросы (JSON). Эта свободная СУБД создана на основе СУБД Postgres, которая разрабатывалась в Калифорнийском университете в Беркли.
Ниже приведен синтаксис UPDATE , используемый в PostgreSQL:
[ WITH [ RECURSIVE ] with_query [, . ] ] UPDATE [ ONLY ] table_name [ * ] [ [ AS ] alias ] SET < column_name = < expression | DEFAULT >| ( column_name [, . ] ) = [ ROW ] ( < expression | DEFAULT >[, . ] ) | ( column_name [, . ] ) = ( sub-SELECT ) > [, . ] [ FROM from_item [, . ] ] [ WHERE condition | WHERE CURRENT OF cursor_name ] [ RETURNING * | output_expression [ [ AS ] output_name ] [, . ] ]
Oracle Database
Oracle Database — это проприетарная комплексная облачная объектно-реляционная СУБД. Ее создала Oracle Corporation.
Ниже приведен синтаксис UPDATE (схема того, как работают запросы), используемый в Oracle Database:
Схема оператора UPDATE из документации Oracle
Примеры работы с оператором SQL UPDATE

Возьмем за пример таблицу с рейтингом СУБД по оценке PYPL индекс популярности языков программирования по запросам в Google за февраль 2023 г. Назовем ее db_ranking .
| Rank | RDBMS | DBShare | Trend |
| 1 | Oracle | 26.79 | -3.7 |
| 2 | MySQL | 19.24 | 2.7 |
| 3 | SQL Server | 12.21 | -1.3 |
| 4 | PostgreSQL | 6.48 | 1.6 |
| 5 | Microsoft Access | 6.42 | -1.7 |
Для онлайн-работы с примерами можно использовать ресурс SQL Fiddle. На нем представлены все СУРБД, которые пересчислены выше. Выбрать нужную СУРБД можно в выпадающем списке справа от логотипа SQL Fiddle.

Интерфейс SQL Fiddle
Для создания таблицы и наполнения ее исходными значениями используем следующий код:
CREATE TABLE db_ranking ( Rank int, RDBMS varchar(255), DBShare float, Trend float ); INSERT INTO db_ranking VALUES (1, 'Oracle', 26.79, -3.7); INSERT INTO db_ranking VALUES (2, 'MySQL', 19.24, 2.7); INSERT INTO db_ranking VALUES (3, 'SQL Server', 12.21, -1.3); INSERT INTO db_ranking VALUES (4, 'PostgreSQL', 6.48, 1.6); INSERT INTO db_ranking VALUES (5, 'Microsoft Access', 6.42, -1.7);
Введите этот запрос в левой панели (Schema Panel) и нажмите кнопку Build Schema.
Пример 1. Изменим долю Oracle на 30,49 % (такое значение для этой СУБД было в 2022 году)
В правой панели введите следующий код для изменения записи и ее последующего просмотра:
UPDATE db_ranking SET DBShare = 30.49 WHERE RDBMS = 'Oracle'; SELECT * FROM db_ranking WHERE RDBMS = 'Oracle';
Результат выполнения запроса:
| Rank | RDBMS | DBShare | Trend |
| 1 | Oracle | 30.49 | -3.7 |
Пример 2. Обнулим отрицательное значение Trend для строк с DBShare > 10
Эту задачу можно выполнить двумя способами — (1) с использованием оператора AND или (2) с использованием оператора OR — в зависимости от того, как мы понимаем условия и какой результат хотим получить.
Чтобы использовать оператор AND для этой задачи, сначала мы обнулим значение Trend для всех строк таблицы, где это значение меньше нуля, а значение DBShare больше 10. Затем просмотрим все строки таблицы.
Обратите внимание: даже если вы меняете запрос в правой панели SQL Fiddle, то запрос на создание таблицы будет выполнен снова, то есть, действия будут производиться над исходной таблицей.
UPDATE db_ranking SET Trend = 0 WHERE Trend < 0 AND DBShare >10; SELECT * FROM db_ranking;
| Rank | RDBMS | DBShare | Trend |
| 1 | Oracle | 26.79 | 0 |
| 2 | MySQL | 19.24 | 2.7 |
| 3 | SQL Server | 12.21 | 0 |
| 4 | PostgreSQL | 6.48 | 1.6 |
| 5 | Microsoft Access | 6.42 | -1.7 |
Если мы хотим использовать вместо AND оператор OR , нам нужно отобрать для изменения те строки исходной таблицы, в которых либо Trend меньше нуля, либо DBShare больше 10.
Запрос будет выглядеть так:
UPDATE db_ranking SET Trend = 0 WHERE Trend < 0 OR DBShare >10; SELECT * FROM db_ranking;
| Rank | RDBMS | DBShare | Trend |
| 1 | Oracle | 26.79 | 0 |
| 2 | MySQL | 19.24 | 0 |
| 3 | SQL Server | 12.21 | 0 |
| 4 | PostgreSQL | 6.48 | 1.6 |
| 5 | Microsoft Access | 6.42 | 0 |
Узнайте, какой оператор SQL подходит лучше всего для вашего конкретного таска — приходите на курс по аналитике данных от robot_dreams.
Пример 3. Обнулим значения DBShare и Trend для всех строк в таблице
Пишем простой запрос на изменение данных, но чтобы оно затронуло все строки таблицы, не используем оператор WHERE .
UPDATE db_ranking SET DBShare = 0, Trend = 0; SELECT * FROM db_ranking;
| Rank | RDBMS | DBShare | Trend |
| 1 | Oracle | 0 | 0 |
| 2 | MySQL | 0 | 0 |
| 3 | SQL Server | 0 | 0 |
| 4 | PostgreSQL | 0 | 0 |
| 5 | Microsoft Access | 0 | 0 |
Пример 4. Изменим N строк в произвольном порядке
Для работы с T-SQL выберите MS SQL Server в выпадающем списке справа от логотипа.
Оператор TOP(n) в инструкции UPDATE позволяет выбрать из таблицы n строк в произвольном порядке. Например:
UPDATE TOP(10) employees SET vacation_hours = vacation_hours * 1.25;
Также можно отобрать и определенный процент строк. Это делается с помощью аргумента PERCENT :
UPDATE TOP(10) PERCENT employees SET vacation_hours = vacation_hours * 1.25;
К нашей таблице можно отправить, например, такой запрос на обнуление рейтинга в трех строках в произвольном порядке:
UPDATE TOP(3) db_ranking SET Rank = 0;
Вот что можем получить в результате исполнения запроса:

В MySQL для ограничения количества строк используется оператор LIMIT . Код для MySQL будет выглядеть так (в SQL Fiddle его необходимо ввести в левой панели после операторов INSERT ):
UPDATE db_ranking SET Rank = 0 LIMIT 3;
В PostgreSQL и Oracle Database используется оператор FETCH с запросом SELECT :
UPDATE db_ranking SET Rank = 0 WHERE RDBMS IN (SELECT RDBMS FROM db_ranking FETCH FIRST 3 ROWS ONLY);
Заключение
Мы рассмотрели базовые примеры применения оператора SQL UPDATE .
Оператор UPDATE позволяет изменять значения в ячейках таблице с указанием столбцов и строк, которые будут затронуты изменением. Основной синтаксис этого оператора в разных диалектах SQL в целом похож, но есть и отличия, характерные для отдельных СУРБД.
Подробную информацию об особенностях использования оператора UPDATE в расширениях SQL, рассмотренных в этой статье, вы можете найти в руководствах по Transact-SQL, MySQL, PostgreSQL и Oracle Database.

В завершение — парочка видео об использовании оператора UPDATE :
А если хотите изучить SQL глубже и под присмотром опытных менторов, приходите в robot_dreams. На их курсе вы сможете освоить профессию Junior Data Analyst всего за 16 недель.

Статья с партнерскими ссылками Этот материал содержит ссылки на партнеров — это не влияет на контент и политику редакции, но дает изданию возможность для развития.
UPDATE (Transact-SQL)
Изменяет существующие данные в таблице или представлении в SQL Server. Примеры см. в разделе Примеры.
Синтаксис
-- Syntax for SQL Server and Azure SQL Database [ WITH [. n] ] UPDATE [ TOP ( expression ) [ PERCENT ] ] < < table_alias | | rowset_function_limited [ WITH ( [ . n ] ) ] > | @table_variable > SET < column_name = < expression | DEFAULT | NULL >| < udt_column_name.< < property_name = expression | field_name = expression >| method_name ( argument [ . n ] ) > > | column_name < .WRITE ( expression , @Offset , @Length ) >| @variable = expression | @variable = column = expression | column_name < += | -= | *= | /= | %= | &= | ^= | |= >expression | @variable < += | -= | *= | /= | %= | &= | ^= | |= >expression | @variable = column < += | -= | *= | /= | %= | &= | ^= | |= >expression > [ . n ] [ ] [ FROM < > [ . n ] ] [ WHERE < | < [ CURRENT OF < < [ GLOBAL ] cursor_name >| cursor_variable_name > ] > > ] [ OPTION ( [ . n ] ) ] [ ; ] ::=
-- Syntax for Azure Synapse Analytics and Microsoft Fabric [ WITH [ . n ] ] UPDATE [ database_name . [ schema_name ] . | schema_name . ] table_name SET < column_name = < expression | NULL >> [ . n ] FROM [ database_name . [ schema_name ] . | schema_name . ] table_name JOIN >[ . n ] ON [ WHERE ] [ OPTION ( LABEL = label_name ) ] [;] ::= < [ database_name . [ schema_name ] . | schema_name . ] table_or_view_name [ AS ] table_or_view_alias [ ] | derived_table [ AS ] table_alias [ ( column_alias [ . n ] ) ] >
-- Syntax for Parallel Data Warehouse UPDATE [ database_name . [ schema_name ] . | schema_name . ] table_name SET < column_name = < expression | NULL >> [ . n ] [ FROM from_clause ] [ WHERE ] [ OPTION ( LABEL = label_name ) ] [;]
Ссылки на описание синтаксиса Transact-SQL для SQL Server 2014 и более ранних версий, см. в статье Документация по предыдущим версиям.
Аргументы
WITH
Задает временный именованный результирующий набор или представление, которые называются обобщенным табличным выражением (CTE), определяемым в пределах области действия инструкции UPDATE. Результирующий набор CTE, на который ссылается инструкция UPDATE, является производным простого запроса.
Обобщенные табличные выражения могут также использоваться с инструкциями SELECT, INSERT, DELETE и CREATE VIEW. Дополнительные сведения см. в статье WITH common_table_expression (Transact-SQL).
TOP (expression) [ PERCENT ]
Задает число или процент обновляемых строк. expression может быть либо числом, либо процентом от числа строк.
Строки, на которые ссылается выражение TOP, используемое с инструкциями INSERT, UPDATE и DELETE, не упорядочиваются.
Инструкции INSERT, UPDATE и DELETE требуют заключения expression в круглые скобки в TOP. Дополнительные сведения см. в разделе TOP (Transact-SQL).
table_alias
Псевдоним, указанный в предложении UPDATE, представляющий таблицу или представление, из которого должны обновляться строки.
server_name
Имя сервера (с использованием имени связанного сервера или функции OPENDATASOURCE в качестве имени сервера), на котором расположена таблица или представление. Если указано server_name, необходимо указать database_name и schema_name.
database_name
Имя базы данных.
schema_name
Имя схемы, которой принадлежит таблица или представление.
table_or_view_name
Имя таблицы или представления, из которых должны обновляться строки. Представление, на которое ссылается аргумент table_or_view_name, должно быть обновляемым и ссылаться только на одну базовую таблицу в предложении FROM в представлении. Дополнительные сведения об обновляемых представлениях см. в разделе CREATE VIEW (Transact-SQL).
rowset_function_limited
Функция OPENQUERY или OPENROWSET, в зависимости от возможностей поставщика.
WITH ()
Задает одно или несколько табличных указаний, разрешенных для целевой таблицы. Ключевое слово WITH и круглые скобки обязательны. NOLOCK, READUNCOMMITTED, NOEXPAND и некоторые другие не допускаются. Сведения о табличных указаниях см. в разделе Табличные указания (Transact-SQL).
@table_variable
Задает переменную table в качестве источника таблицы.
SET
Задает список обновляемых имен столбцов или переменных.
column_name
Столбец, содержащий изменяемые данные. Аргумент column_name должен существовать в table_or view_name. Столбцы идентификаторов не могут быть обновлены.
expression
Переменная, литеральное значение, выражение или инструкция подзапроса выборки (заключенная в скобки), которые возвращают единственное значение. Значение, возвращаемое expression, заменяет существующее значение в column_name или @variable.
При ссылке на типы данных символов Юникода nchar, nvarchar и ntext выражение ‘expression’ должно начинаться с заглавной буквы ‘N’. Если префикс «N» не указан, SQL Server выполнит преобразование строки в кодовую страницу, соответствующую параметрам сортировки базы данных или столбца, действующим по умолчанию. Любые символы, не входящие в эту кодовую страницу, будут утрачены.
DEFAULT
Указывает, что существующее в столбце значение будет заменено значением по умолчанию, определенным для данного столбца. Также может использоваться для присвоения значения NULL, если столбец не имеет значений по умолчанию и может принимать значения NULL.
< += | -= | *= | /= | %= | &= | ^= | |= >
Составной оператор присваивания:
+= Сложение и присваивание
-= Вычитание и присваивание
*= Умножение и присваивание
/= Деление и присваивание
%= Остаток от деления и присваивание
&= Выполнение побитовой операции AND и присваивание
^= Выполнение побитовой операции XOR и присваивание
|= Выполнение побитовой операции OR и присваивание
udt_column_name
Столбец определяемого пользователем типа.
property_name | field_name
Общедоступное свойство или общедоступный элемент данных определяемого пользоватлем типа.
method_name(argument [ ,. n] )
Не статичный метод общего мутатора udt_column_name, принимающий один или несколько аргументов.
.WRITE (expression,@Offset,@Length)
Указывает, что часть значения column_name будет изменена. expression заменяет единицы @Length начиная с @Offset в column_name. В этом предложении можно указать только столбцы типа varchar(max) , nvarchar(max) или varbinary(max) . Аргумент column_name не может иметь значение NULL и не может быть задан именем или псевдонимом таблицы.
expression является значением, которое копируется в column_name. Аргумент expression должен преобразовываться или поддерживать неявное преобразование к типу column_name. Если для expression установлено значение NULL, @Length не учитывается, а значение в column_name усекается с позиции, на которую указывает аргумент @Offset.
Аргумент @Offset — это начальная точка в значении, хранимом в column_name, начиная с которой записывается expression.Аргумент @Offset задает последовательную позицию разряда, начиная с 0, имеет тип bigint и не может быть отрицательным. Если аргумент @Offset имеет значение NULL, операция обновления добавляет значение expression в конце существующего значения аргумента column_name, а аргумент @Length пропускается. Если значение аргумента @Offset больше, чем байтовая длина значения аргумента column_name, компонент Компонент Database Engine возвращает ошибку. Если сумма значений @Offset и @Length превышает длину базового значения столбца, удаление выполняется до последнего символа этого значения.
Аргумент @Length задает длину части значения столбца начиная с @Offset, которая заменяется на выражение expression.Аргумент @Length имеет тип bigint и не может быть отрицательным. Если аргумент @Length имеет значение NULL, операция обновления удаляет все данные, начиная со значения @Offset до конца значения column_name.
Дополнительные сведения см. ниже в разделе Обновление типов данных большого объема.
@variable
Объявленная переменная, которой присваивается значение, возвращенное expression.
Предложение SET @variable = column = expression присваивает переменной то же значение, что и столбцу. Это отличается от предложения SET @variable = column, column = expression, присваивающего переменной значение столбца до обновления.
Возвращает обновленные данные или основанные на них выражения в рамках выполнения операции UPDATE. Предложение OUTPUT не поддерживается ни в одной инструкции DML, целью которой являются удаленные таблицы или представления. Дополнительные сведения об аргументах и логике работы этого предложения см. в статье Предложение OUTPUT (Transact-SQL).
FROM
Определяет, что для определения критериев операции обновления используется таблица, представление или производная таблица. Дополнительные сведения см. в разделе FROM (Transact-SQL).
Если обновляемый объект совпадает с объектом в предложении FROM, а в предложении FROM имеется только одна ссылка на этот объект, псевдоним объекта указывать не обязательно. Если обновляемый объект встречается в предложении FROM несколько раз, одна и только одна ссылка на этот объект не должна указывать псевдоним таблицы. Все остальные ссылки на объект в предложении FROM должны включать псевдоним объекта.
Представление с триггером INSTEAD OF UPDATE не может быть целью инструкции UPDATE с предложением FROM.
Любой вызов функции OPENDATASOURCE, OPENQUERY или OPENROWSET в предложении FROM вычисляется отдельно и независимо от любого вызова этих функций, используемого как назначение при обновлении, даже если в двух таких вызовах будут заданы идентичные аргументы. В частности, условия фильтра или соединения, применяемые к результатам одного из таких вызовов, никак не влияют на результаты другого.
WHERE
Задает условия, ограничивающие обновляемые строки. Существует два вида обновлений в зависимости от используемой формы предложения WHERE.
- В поисковых обновлениях задается условие поиска строк, предназначенных к удалению.
- В позиционных обновлениях используется предложение CURRENT OF для указания курсора. Операция обновления выполняется в текущем положении курсора.
Задает условие, которому должны удовлетворять обновляемые строки. Условие поиска может также представлять собой условие, на котором основано соединение. Количество предикатов, которое может содержать условие поиска, не ограничено. Дополнительные сведения об условиях поиска и предикатах см. в статье Условие поиска (Transact-SQL).
CURRENT OF
Определяет, что обновление выполняется в текущей позиции указанного курсора.
Позиционированное обновление с использованием предложения WHERE CURRENT OF обновляет единственную строку в текущем положении курсора. Такое обновление может быть более точным, чем поисковое обновление, в котором для выбора строк используется предложение WHERE . Если условие поиска не определяет однозначно единственную строку, поисковое обновление изменяет несколько строк.
GLOBAL
Указывает, что аргумент cursor_name ссылается на глобальный курсор.
cursor_name
Имя открытого курсора, из которого должна быть произведена выборка. Если существует как глобальный, так и локальный курсор с именем cursor_name, этот аргумент ссылается на глобальный курсор, если указан аргумент GLOBAL, в противном случае он ссылается на локальный курсор. Курсор должен позволять производить обновления.
cursor_variable_name
Имя переменной курсора. Аргумент cursor_variable_name должен содержать ссылку на курсор, обновления которого разрешены.
OPTION ( [ ,. n ] )
Определяет, что для настройки способа, которым компонент Компонент Database Engine обрабатывает инструкцию, используются подсказки оптимизатора. Дополнительные сведения см. в разделе Указания запросов (Transact-SQL).
Рекомендации
Для возврата в клиентское приложение количества вставленных строк используйте функцию @@ROWCOUNT . Дополнительные сведения см. в разделе @@ROWCOUNT (Transact-SQL).
В инструкции UPDATE можно использовать имена переменных для показа старых и новых значений, но только в том случае, если инструкция UPDATE обрабатывает одну запись. Если инструкция UPDATE затрагивает несколько записей, для возвращения старых и новых значений каждой записи используйте предложение OUTPUT.
Проявляйте осторожность, указывая предложение FROM при задании критериев для операции обновления. Результаты инструкции UPDATE не определены, если инструкция включает предложение FROM, в котором для каждого вхождения обновляемого столбца не задано единственное значение, то есть если инструкция UPDATE не является детерминированной. Например, в инструкции UPDATE следующего скрипта обе строки в Table1 удовлетворяют условиям предложения FROM в инструкции UPDATE, но не определено, какая строка из Table1 используется для обновления строки в Table2.
USE AdventureWorks2022; GO IF OBJECT_ID ('dbo.Table1', 'U') IS NOT NULL DROP TABLE dbo.Table1; GO IF OBJECT_ID ('dbo.Table2', 'U') IS NOT NULL DROP TABLE dbo.Table2; GO CREATE TABLE dbo.Table1 (ColA INT NOT NULL, ColB DECIMAL(10,3) NOT NULL); GO CREATE TABLE dbo.Table2 (ColA INT PRIMARY KEY NOT NULL, ColB DECIMAL(10,3) NOT NULL); GO INSERT INTO dbo.Table1 VALUES(1, 10.0), (1, 20.0); INSERT INTO dbo.Table2 VALUES(1, 0.0); GO UPDATE dbo.Table2 SET dbo.Table2.ColB = dbo.Table2.ColB + dbo.Table1.ColB FROM dbo.Table2 INNER JOIN dbo.Table1 ON (dbo.Table2.ColA = dbo.Table1.ColA); GO SELECT ColA, ColB FROM dbo.Table2;
Та же проблема может возникнуть при объединении предложений FROM и WHERE CURRENT OF . В следующем примере обе строки в Table2 удовлетворяют условиям предложения FROM в инструкции UPDATE . Не определено, какая строка из Table2 должна использоваться для обновления строки в Table1 .
USE AdventureWorks2022; GO IF OBJECT_ID ('dbo.Table1', 'U') IS NOT NULL DROP TABLE dbo.Table1; GO IF OBJECT_ID ('dbo.Table2', 'U') IS NOT NULL DROP TABLE dbo.Table2; GO CREATE TABLE dbo.Table1 (c1 INT PRIMARY KEY NOT NULL, c2 INT NOT NULL); GO CREATE TABLE dbo.Table2 (d1 INT PRIMARY KEY NOT NULL, d2 INT NOT NULL); GO INSERT INTO dbo.Table1 VALUES (1, 10); INSERT INTO dbo.Table2 VALUES (1, 20), (2, 30); GO DECLARE abc CURSOR LOCAL FOR SELECT c1, c2 FROM dbo.Table1; OPEN abc; FETCH abc; UPDATE dbo.Table1 SET c2 = c2 + d2 FROM dbo.Table2 WHERE CURRENT OF abc; GO SELECT c1, c2 FROM dbo.Table1; GO
Поддержка совместимости
Поддержка использования подсказок READUNCOMMITTED и NOLOCK в предложении FROM, применяемом к целевой таблице инструкции UPDATE или DELETE, будет удалена в следующей версии SQL Server. Следует избегать использования этих указаний в таком контексте в новой разработке и запланировать изменение приложений, использующих их в настоящий момент.
Типы данных
Все столбцы, имеющие тип данных char и nchar, дополняются справа до заданной длины.
Если параметр ANSI_PADDING имеет значение OFF, все конечные пробелы удаляются из данных, вставленных в столбцы varchar и nchar, за исключением строк, содержащих только пробелы. Эти строки усекаются до пустых строк. Если ANSI_PADDING имеет значение ON, вставляются конечные пробелы. Драйвер ODBC для Microsoft SQL Server и поставщик OLE DB для SQL Server автоматически устанавливают ANSI_PADDING ON для каждого соединения. Этот параметр можно настроить в источниках данных ODBC или устанавливая атрибуты или свойства соединений. Дополнительные сведения см. в разделе SET ANSI_PADDING (Transact-SQL).
Обновление столбцов типа text, ntext и image
Изменение столбцов типа text, ntext или image с помощью инструкции UPDATE инициализирует столбец, присваивает ему допустимый текстовый указатель и выделяет по крайней мере одну страницу данных, если столбец не обновляется значением NULL.
Чтобы заменить или изменить большие блоки данных типа text, ntext или image, вместо UPDATE используется инструкция WRITETEXT или UPDATETEXT.
Если инструкция UPDATE могла обновить несколько строк при обновлении как ключа кластеризации, так и одного или нескольких столбцов типа text, ntext или image, то частичное обновление этих столбцов выполняется как полная замена значений.
Типы данных ntext, text и image будут удалены в следующей версии Microsoft SQL Server. Следует избегать использования этих типов данных при новой разработке и запланировать изменение приложений, использующих их в настоящий момент. Вместо них следует использовать типы данных nvarchar(max), varchar(max)и varbinary(max) .
Обновление типов данных большого объема
Используйте предложение .WRITE (expression,@Offset,@Length) для выполнения частичного или полного обновления типов данных varchar(max), nvarchar(max) и varbinary(max).
Например, частичное обновление столбца с типом varchar(max) может удалить или изменить только первые 200 байтов в столбце (200 символов при использовании символов ASCII), тогда как полное обновление удалит или изменит все данные в столбце. Обновления .WRITE, вставляющие или добавляющие новые данные, имеют минимальное протоколирование, если установлена простая модель восстановления базы данных или модель восстановления с неполным протоколированием. Если обновляются существующие значения, ведение журнала не сокращается до минимума. Дополнительные сведения см. в статье Журнал транзакций (SQL Server).
Компонент Компонент Database Engine преобразует частичное обновление в полное, если инструкция UPDATE приводит к одному из следующих действий.
- Изменения ключевого столбца секционированного представления или таблицы.
- Изменение более одной строки, а также обновление ключа неуникального кластеризованного индекса на непостоянное значение.
Нельзя использовать предложение .WRITE для обновления столбца NULL или присваивания аргументу column_name значения NULL.
Параметры @Offset и @Length указываются в байтах для типов данных varbinary и varchar и в байтовых парах для типа данных nvarchar. Дополнительные сведения о длине строковых типов данных см. в разделах char и varchar (Transact-SQL) и nchar и nvarchar (Transact-SQL).
В целях увеличения производительности рекомендуется вставлять или обновлять данные фрагментами, кратными 8040 байтам.
Если на столбец, измененный предложением .WRITE, ссылается предложение OUTPUT, полное значение столбца, либо исходный образ в deleted.column_name, либо преобразованный образ в inserted.column_name, возвращается определенному столбцу в табличной переменной. См. пример Т ниже.
Чтобы добиться функциональности предложения .WRITE при обработке других символьных или двоичных типов данных, используется STUFF (Transact-SQL).
Обновление столбцов определяемого пользователем типа
Обновление столбцов определяемого пользователем типа можно выполнить одним из следующих способов.
-
Предоставление значения типа системных данных SQL Server происходит, если определяемый пользователем тип поддерживает явное или неявное преобразование из этого типа. Следующий пример демонстрирует, как обновить значение в столбце определяемого пользователем типа Point путем явного преобразования строки.
UPDATE Cities SET Location = CONVERT(Point, '12.3:46.2') WHERE Name = 'Anchorage';
UPDATE Cities SET Location.SetXY(23.5, 23.5) WHERE Name = 'Anchorage';
Примечание SQL Server возвращает ошибку, если метод мутатора возвращает значение NULL языка Transact-SQL либо если новое значение, порожденное методом мутатора, соответствует значению NULL.
UPDATE Cities SET Location.X = 23.5 WHERE Name = 'Anchorage';
Обновление данных FILESTREAM
Инструкция UPDATE позволяет обновить поля FILESTREAM значением NULL, пустым значением или встроенными данными относительно небольшого размера. Однако при работе с большими объемами данных более эффективно передавать поток в файл с использованием интерфейсов Win32. При обновлении поля FILESTREAM происходит изменение базовых данных BLOB в файловой системе. Если в поле FILESTREAM содержится значение NULL, данные BLOB, связанные с этим полем, удаляются. Для частичного обновления данных потока FILESTREAM недопустимо использовать метод .WRITE(). Дополнительные сведения см. в разделе FILESTREAM (SQL Server).
Обработка ошибок
Если обновление строки нарушает ограничение, правило или установку NULL для столбца либо новое значение имеет несовместимый тип данных, то инструкция отменяется, возвращается ошибка и никакие записи не обновляются.
Если инструкция UPDATE при оценке выражения встречает арифметическую ошибку (переполнение, деление на ноль или ошибку домена), обновление не выполняется. Остальная часть пакета не выполняется и возвращается сообщение об ошибке.
Если обновление столбца или столбцов, участвующих в кластеризованном индексе, приводит к тому, что размер кластеризованного индекса и строки превышает 8 060 байт, обновление заканчивается неудачей и возвращается сообщение об ошибке.
Совместимость
Инструкции UPDATE разрешается использовать в теле определяемых пользователем функций только в том случае, если изменяемая таблица является табличной переменной.
Если для операций UPDATE по отношению к таблице определен триггер INSTEAD OF , вместо инструкции UPDATE запускается этот триггер. Ранние версии SQL Server поддерживали для UPDATE и других инструкций изменения данных только определение триггеров AFTER. В инструкции UPDATE, которая прямо или косвенно ссылается на представление с определенным для него триггером INSTEAD OF , не может быть указано предложение FROM. Дополнительные сведения о триггерах INSTEAD OF см. в разделе CREATE TRIGGER (Transact-SQL).
В настоящее время предложение FROM не может быть указано в инструкции UPDATE на складе в Microsoft Fabric. Поддерживаются инструкции UPDATE для одной таблицы.
ограничения
В инструкции UPDATE, которая прямо или косвенно ссылается на представление с определенным для него триггером INSTEAD OF , не может быть указано предложение FROM. Дополнительные сведения о триггерах INSTEAD OF см. в разделе CREATE TRIGGER (Transact-SQL).
Если обобщенное табличное выражение указывается в качестве цели инструкции UPDATE, должны совпадать все ссылки на это выражение в инструкции. Например, если для обобщенного табличного выражения в предложении FROM назначается псевдоним, то этот псевдоним должен использоваться для всех остальных ссылок на обобщенное табличное выражение. Требуются однозначные ссылки на обобщенное табличное выражение, так как обобщенное табличное выражение не имеет идентификатор объекта, который SQL Server использует для распознавания неявной связи между объектом и его псевдонимом. В отсутствие такой связи план запроса может непредвиденным образом построить работу с соединениями, что приведет к нежелательным результатам запроса. В следующих примерах показаны правильные и неправильные методы задания обобщенного табличного выражения, когда оно является целевым объектом операции обновления.
USE tempdb; GO -- UPDATE statement with CTE references that are correctly matched. DECLARE @x TABLE (ID INT, Value INT); DECLARE @y TABLE (ID INT, Value INT); INSERT @x VALUES (1, 10), (2, 20); INSERT @y VALUES (1, 100),(2, 200); WITH cte AS (SELECT * FROM @x) UPDATE x -- cte is referenced by the alias. SET Value = y.Value FROM cte AS x -- cte is assigned an alias. INNER JOIN @y AS y ON y.ID = x.ID; SELECT * FROM @x; GO
ID Value ------ ----- 1 100 2 200 (2 row(s) affected)
Инструкция UPDATE с неправильно подобранными ссылками на обобщенное табличное выражение.
USE tempdb; GO DECLARE @x TABLE (ID INT, Value INT); DECLARE @y TABLE (ID INT, Value INT); INSERT @x VALUES (1, 10), (2, 20); INSERT @y VALUES (1, 100),(2, 200); WITH cte AS (SELECT * FROM @x) UPDATE cte -- cte is not referenced by the alias. SET Value = y.Value FROM cte AS x -- cte is assigned an alias. INNER JOIN @y AS y ON y.ID = x.ID; SELECT * FROM @x; GO
ID Value ------ ----- 1 100 2 100 (2 row(s) affected)
Режим блокировки
Инструкция UPDATE получает монопольную блокировку (X) на строки, которые она изменяет, и держит блокировку до тех пор, пока транзакция не завершится. В зависимости от плана запроса для инструкции UPDATE, количества изменяемых строк и уровня изоляции транзакции, блокировки могут быть получены на уровне страницы или на уровне таблицы, а не на уровне строк. Чтобы избежать этих блокировок более высокого уровня, можно разделить инструкцию UPDATE, которая распространяется на тысячи или более строк, на пакеты и убедиться, что все условия объединения и фильтрации поддерживаются индексами. Дополнительные сведения о блокировке механизмов в SQL Server см. в статье Блокировка в ядре СУБД.
Режим ведения журнала
Инструкция UPDATE записывается в журнал, однако частичные обновления типов данных с большими значениями с использованием предложения .WRITE регистрируются на минимальном уровне. Дополнительные сведения см. ниже в подразделе «Обновление типов данных большого объема» приведенного ранее раздела «Типы данных».
Безопасность
Разрешения
Разрешения UPDATE необходимы для целевой таблицы. Кроме того, требуются разрешения на выполнение SELECT для обновляемой таблицы, если инструкция UPDATE содержит предложение WHERE или если аргумент expression в предложении SET использует столбец в этой таблице.
Разрешения UPDATE по умолчанию предоставляются членам предопределенной роли сервера sysadmin , членам предопределенных ролей баз данных db_owner и db_datawriter , а также владельцу таблицы. Члены ролей sysadmin , db_owner и db_securityadmin , а также владелец таблицы могут передавать разрешения другим пользователям.
Примеры
| Категория | Используемые элементы синтаксиса |
|---|---|
| Базовый синтаксис | UPDATE |
| Ограничение обновляемых строк | WHERE * TOP * WITH common table expression * WHERE CURRENT OF |
| Установка значений столбца | вычисляемые значения * составные операторы * значения по умолчанию * вложенные запросы |
| Указание целевых объектов, отличных от стандартных таблиц | views * табличные переменные * псевдонимы таблиц |
| Обновление данных на основе данных из других таблиц | FROM |
| Обновление строк в удаленной таблице | связанный сервер * OPENQUERY * OPENDATASOURCE |
| Обновление типов данных больших объектов | . WRITE * OPENROWSET |
| Обновление определяемых пользователем типов данных | определяемые пользователем типы |
| Переопределение поведения по умолчанию для оптимизатора запросов с помощью указаний | табличные подсказки * указания запросов |
| Сбор результатов выполнения инструкции UPDATE | OUTPUT, предложение |
| Использование инструкции UPDATE в других инструкциях | Хранимые процедуры * TRY. ПОЙМАТЬ |
Базовый синтаксис
В примерах в этом разделе описывается базовая функциональность инструкции UPDATE с помощью минимального необходимого синтаксиса.
A. Использование простой инструкции UPDATE
В следующем примере обновляется один столбец для всех строк в таблице Person.Address .
USE AdventureWorks2022; GO UPDATE Person.Address SET ModifiedDate = GETDATE();
Б. Обновление нескольких столбцов
В следующем примере выполняется обновление значений в столбцах Bonus , CommissionPct и SalesQuota для всех строк в таблице SalesPerson .
USE AdventureWorks2022; GO UPDATE Sales.SalesPerson SET Bonus = 6000, CommissionPct = .10, SalesQuota = NULL; GO
Ограничение обновляемых строк
В примерах в этом разделе описываются способы ограничения количества строк, на которые влияет инструкция UPDATE.
В. Применение предложения WHERE
В следующем примере предложение WHERE используется для указания строк, которые необходимо обновить. Инструкция обновляет значение в столбце Color таблицы Production.Product для всех строк, в которых имеется существующее значение Red в столбце Color и имеется значение в столбце Name , который начинается с Road-250.
USE AdventureWorks2022; GO UPDATE Production.Product SET Color = N'Metallic Red' WHERE Name LIKE N'Road-250%' AND Color = N'Red'; GO
Г. Использование предложения TOP
В следующем примере предложение TOP используется для ограничения числа строк, изменяемых в процессе выполнения инструкции UPDATE. Если в инструкции UPDATE указано предложение TOP (n), то операция обновления выполняется для произвольного подмножества в n строк. В следующем примере в столбце VacationHours для случайных 10 строк таблицы Employee значение меняется на 25 %.
USE AdventureWorks2022; GO UPDATE TOP (10) HumanResources.Employee SET VacationHours = VacationHours * 1.25 ; GO
Если нужно применить изменения с предложением TOP в определенной последовательности, укажите во вложенной инструкции выборки инструкцию ORDER BY. В следующем примере изменяется длительность отпуска для 10 сотрудников, имеющих наибольший стаж работы.
UPDATE HumanResources.Employee SET VacationHours = VacationHours + 8 FROM (SELECT TOP 10 BusinessEntityID FROM HumanResources.Employee ORDER BY HireDate ASC) AS th WHERE HumanResources.Employee.BusinessEntityID = th.BusinessEntityID; GO
Д. Использование предложения WITH обобщенное_табличное_выражение
В следующем примере обновляется значение PerAssemblyQty для всех частей и компонентов, прямо или косвенно используемых для создания ProductAssemblyID 800 . Обобщенное табличное выражение возвращает иерархический список частей, которые непосредственно используются для сборки ProductAssemblyID 800 , и частей, которые используются для сборки этих компонентов, и т. д. Изменяются только строки, возвращенные обобщенным табличным выражением.
USE AdventureWorks2022; GO WITH Parts(AssemblyID, ComponentID, PerAssemblyQty, EndDate, ComponentLevel) AS ( SELECT b.ProductAssemblyID, b.ComponentID, b.PerAssemblyQty, b.EndDate, 0 AS ComponentLevel FROM Production.BillOfMaterials AS b WHERE b.ProductAssemblyID = 800 AND b.EndDate IS NULL UNION ALL SELECT bom.ProductAssemblyID, bom.ComponentID, p.PerAssemblyQty, bom.EndDate, ComponentLevel + 1 FROM Production.BillOfMaterials AS bom INNER JOIN Parts AS p ON bom.ProductAssemblyID = p.ComponentID AND bom.EndDate IS NULL ) UPDATE Production.BillOfMaterials SET PerAssemblyQty = c.PerAssemblyQty * 2 FROM Production.BillOfMaterials AS c JOIN Parts AS d ON c.ProductAssemblyID = d.AssemblyID WHERE d.ComponentLevel = 0;
Е. Использование предложения WHERE CURRENT OF
В следующем примере предложение WHERE CURRENT OF используется только для обновления строк, на которых установлен курсор. Если курсор основан на соединении, изменяется только таблица table_name , указанная в инструкции UPDATE. Другие таблицы, участвующие в курсоре, не затрагиваются.
USE AdventureWorks2022; GO DECLARE complex_cursor CURSOR FOR SELECT a.BusinessEntityID FROM HumanResources.EmployeePayHistory AS a WHERE RateChangeDate <> (SELECT MAX(RateChangeDate) FROM HumanResources.EmployeePayHistory AS b WHERE a.BusinessEntityID = b.BusinessEntityID) ; OPEN complex_cursor; FETCH FROM complex_cursor; UPDATE HumanResources.EmployeePayHistory SET PayFrequency = 2 WHERE CURRENT OF complex_cursor; CLOSE complex_cursor; DEALLOCATE complex_cursor; GO
Установка значений столбца
В примерах этого раздела описывается обновление столбцов с помощью вычисляемых значений, вложенных запросов и значений DEFAULT.
Ж. Указание вычисляемого значения
В следующих примерах используются вычисляемые значения в инструкции UPDATE. В примере удваивается значение столбца ListPrice для всех строк в таблице Product .
USE AdventureWorks2022; GO UPDATE Production.Product SET ListPrice = ListPrice * 2; GO
З. Задание составного оператора
В следующем примере демонстрируется использование переменной @NewPrice для увеличения цены красных велосипедов прибавлением 10 к текущей цене.
USE AdventureWorks2022; GO DECLARE @NewPrice INT = 10; UPDATE Production.Product SET ListPrice += @NewPrice WHERE Color = N'Red'; GO
В следующем примере используется составной оператор += для добавления данных ‘ — tool malfunction’ к существующему значению в столбце Name для строк, имеющих значение ScrapReasonID от 10 до 12.
USE AdventureWorks2022; GO UPDATE Production.ScrapReason SET Name += ' - tool malfunction' WHERE ScrapReasonID BETWEEN 10 and 12;
И. Задание вложенного запроса в предложении SET
В следующем примере используется вложенный запрос в предложении SET для определения значения, которое используется для обновления столбца. Вложенный запрос должен возвращать только скалярное значение (то есть одно значение для каждой строки). В примере изменяется столбец SalesYTD в таблице SalesPerson для отображения самой последней информации о продажах, зафиксированной в таблице SalesOrderHeader . Вложенный запрос проводит статистическую обработку сведений о продажах по всем продавцам в инструкции UPDATE .
USE AdventureWorks2022; 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.BusinessEntityID = so.SalesPersonID GROUP BY so.SalesPersonID); GO
К. Обновление строк с использованием значений DEFAULT
В следующем примере для столбца CostRate задается значение по умолчанию (0,00) для всех строк, значение CostRate которых больше 20.00 .
USE AdventureWorks2022; GO UPDATE Production.Location SET CostRate = DEFAULT WHERE CostRate > 20.00;
Указание целевых объектов, отличных от стандартных таблиц
В примерах этого раздела описаны методы обновления строк с указанием представления, псевдонима таблицы или табличной переменной.
Л. Указание представления в качестве целевого объекта
В следующем примере выполняется обновление строк таблицы путем указания представления в качестве целевого объекта. Определение представления ссылается на несколько таблиц, однако инструкция UPDATE была успешно выполнена, поскольку она ссылается на столбцы только одной из базовых таблиц. При выполнении инструкции UPDATE произойдет сбой, если были указаны столбцы из обеих таблиц. Дополнительные сведения см. в разделе Изменение данных через представление.
USE AdventureWorks2022; GO UPDATE Person.vStateProvinceCountryRegion SET CountryRegionName = 'United States of America' WHERE CountryRegionName = 'United States';
М. Задание псевдонима таблицы в качестве целевого объекта
В следующем примере производится обновление строк в таблице Production.ScrapReason . Псевдоним таблицы, заданный для ScrapReason в предложении FROM, указывается как целевой объект в предложении UPDATE.
USE AdventureWorks2022; GO UPDATE sr SET sr.Name += ' - tool malfunction' FROM Production.ScrapReason AS sr JOIN Production.WorkOrder AS wo ON sr.ScrapReasonID = wo.ScrapReasonID AND wo.ScrappedQty > 300;
Н. Задание табличной переменной в качестве целевого объекта
В следующем примере производится обновление строк в табличной переменной.
USE AdventureWorks2022; GO -- Create the table variable. DECLARE @MyTableVar TABLE ( EmpID INT NOT NULL, NewVacationHours INT, ModifiedDate DATETIME); -- Populate the table variable with employee ID values from HumanResources.Employee. INSERT INTO @MyTableVar (EmpID) SELECT BusinessEntityID FROM HumanResources.Employee; -- Update columns in the table variable. UPDATE @MyTableVar SET NewVacationHours = e.VacationHours + 20, ModifiedDate = GETDATE() FROM HumanResources.Employee AS e WHERE e.BusinessEntityID = EmpID; -- Display the results of the UPDATE statement. SELECT EmpID, NewVacationHours, ModifiedDate FROM @MyTableVar ORDER BY EmpID; GO
Обновление данных на основе данных из других таблиц
В примерах этого раздела описаны методы обновления строк одной таблицы на основе данных в другой таблице.
О. Использование инструкции UPDATE с данными из другой таблицы
В следующем примере изменяется столбец SalesYTD в таблице SalesPerson для отображения самой последней информации о продажах, зафиксированной в таблице SalesOrderHeader .
USE AdventureWorks2022; GO UPDATE Sales.SalesPerson SET SalesYTD = SalesYTD + SubTotal FROM Sales.SalesPerson AS sp JOIN Sales.SalesOrderHeader AS so ON sp.BusinessEntityID = so.SalesPersonID AND so.OrderDate = (SELECT MAX(OrderDate) FROM Sales.SalesOrderHeader WHERE SalesPersonID = sp.BusinessEntityID); GO
В предыдущем примере подразумевается, что на конкретного менеджера по продажам на каждую конкретную дату записана только одна продажа и выполнены все текущие обновления. Если в один и тот же день для указанного менеджера может иметься более одной продажи, приведенный пример будет работать неправильно. Пример выполняется без ошибок, но каждое из значений SalesYTD обновляется только для одной из продаж, вне зависимости от действительного количества продаж в этот день. Это происходит потому, что одиночная инструкция UPDATE никогда не обновляет одну и ту же строку дважды.
В ситуации, когда у данного менеджера по продажам имеется несколько продаж в день, все продажи для каждого из менеджеров по продажам должны быть собраны вместе инструкцией UPDATE , как показано в следующем примере.
USE AdventureWorks2022; 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.BusinessEntityID = so.SalesPersonID GROUP BY so.SalesPersonID); GO
Обновление строк в удаленной таблице
В примерах в этом разделе описаны способы обновления строк в удаленной целевой таблице с использованием в качестве ссылки на удаленную таблицу связанного сервера или функции, возвращающей набор строк.
П. Обновление данных в удаленной таблице с использованием связанного сервера
В следующем примере обновляется таблица на удаленном сервере. Этот пример начинается с создания ссылки на удаленный источник данных с помощью хранимой процедуры sp_addlinkedserver. Затем имя связанного сервера MyLinkedServer указывается в качестве одного из четырех компонентов имени объекта в формате сервер.каталог.схема.объект. Обратите внимание, что необходимо указать действительное имя сервера для @datasrc .
USE master; GO -- Create a link to the remote data source. -- Specify a valid server name for @datasrc as 'server_name' or 'server_nameinstance_name'. EXEC sp_addlinkedserver @server = N'MyLinkedServer', @srvproduct = N' ', @provider = N'SQLNCLI10', @datasrc = N'', @catalog = N'AdventureWorks2022'; GO USE AdventureWorks2022; GO -- Specify the remote data source using a four-part name -- in the form linked_server.catalog.schema.object. UPDATE MyLinkedServer.AdventureWorks2022.HumanResources.Department SET GroupName = N'Public Relations' WHERE DepartmentID = 4;
Т. Обновление данных в удаленной таблице с помощью функции OPENQUERY
В следующем примере выполняется обновление строки в удаленной таблице с помощью вызова функции OPENQUERY, возвращающей набор строк. В этом примере используется имя связанного сервера, созданного в предыдущем примере.
UPDATE OPENQUERY (MyLinkedServer, 'SELECT GroupName FROM HumanResources.Department WHERE DepartmentID = 4') SET GroupName = 'Sales and Marketing';
У. Обновление данных в удаленной таблице с помощью функции OPENDATASOURCE
В следующем примере выполняется обновление строки в удаленной таблице с помощью вызова функции OPENDATASOURCE, возвращающей набор строк. Определите допустимое имя сервера для источника данных, используя формат server_name или server_name\instance_name. Возможно, потребуется настроить у экземпляра SQL Server параметр Ad Hoc Distributed Queries. Дополнительные сведения см. в статье Параметр конфигурации сервера «ad hoc distributed queries».
UPDATE OPENDATASOURCE('SQLNCLI', 'Data Source=;Integrated Security=SSPI').AdventureWorks2022.HumanResources.Department SET GroupName = 'Sales and Marketing' WHERE DepartmentID = 4;
Обновление типов данных больших объектов
В примерах в этом разделе описываются методы обновления значений в столбцах, определенных с типами данных больших объектов (LOB).
Ф. Использование инструкции UPDATE с предложением .WRITE для изменения данных в столбце nvarchar(max)
В следующем примере предложение .WRITE используется для обновления частичного значения столбца DocumentSummary типа nvarchar(max) в таблице Production.Document . Слово components заменяется словом features путем указания слова для замены, начального положения (смещения) заменяемого слова в существующих данных и количества заменяемых символов (длины). В этом примере также используется предложение OUTPUT для возврата исходного и преобразованного образов столбца DocumentSummary в табличную переменную @MyTableVar .
USE AdventureWorks2022; GO DECLARE @MyTableVar TABLE ( SummaryBefore NVARCHAR(max), SummaryAfter NVARCHAR(max)); UPDATE Production.Document SET DocumentSummary .WRITE (N'features',28,10) OUTPUT deleted.DocumentSummary, inserted.DocumentSummary INTO @MyTableVar WHERE Title = N'Front Reflector Bracket Installation'; SELECT SummaryBefore, SummaryAfter FROM @MyTableVar; GO
Х. Использование UPDATE с предложением .WRITE для добавления и удаления данных в столбце типа nvarchar(max)
В следующем примере данные добавляются в столбец типа nvarchar(max) , имеющий текущее значение NULL, и удаляются из него. Поскольку предложение .WRITE не может использоваться для изменения столбца со значением NULL, этот столбец сначала заполняется временными данными. Затем они заменяются правильными данными с помощью предложения .WRITE. В дополнительных примерах данные добавляются в конец значения столбца, удаляются из столбца (усекаются) и, наконец, удаляются частичные данные из столбца. Инструкции SELECT выводят на экран изменения данных, создаваемые каждой из инструкций UPDATE.
USE AdventureWorks2022; GO -- Replacing NULL value with temporary data. UPDATE Production.Document SET DocumentSummary = N'Replacing NULL value' WHERE Title = N'Crank Arm and Tire Maintenance'; GO SELECT DocumentSummary FROM Production.Document WHERE Title = N'Crank Arm and Tire Maintenance'; GO -- Replacing temporary data with the correct data. Setting @Length to NULL -- truncates all existing data from the @Offset position. UPDATE Production.Document SET DocumentSummary .WRITE(N'Carefully inspect and maintain the tires and crank arms.',0,NULL) WHERE Title = N'Crank Arm and Tire Maintenance'; GO SELECT DocumentSummary FROM Production.Document WHERE Title = N'Crank Arm and Tire Maintenance'; GO -- Appending additional data to the end of the column by setting -- @Offset to NULL. UPDATE Production.Document SET DocumentSummary .WRITE (N' Appending data to the end of the column.', NULL, 0) WHERE Title = N'Crank Arm and Tire Maintenance'; GO SELECT DocumentSummary FROM Production.Document WHERE Title = N'Crank Arm and Tire Maintenance'; GO -- Removing all data from @Offset to the end of the existing value by -- setting expression to NULL. UPDATE Production.Document SET DocumentSummary .WRITE (NULL, 56, 0) WHERE Title = N'Crank Arm and Tire Maintenance'; GO SELECT DocumentSummary FROM Production.Document WHERE Title = N'Crank Arm and Tire Maintenance'; GO -- Removing partial data beginning at position 9 and ending at -- position 21. UPDATE Production.Document SET DocumentSummary .WRITE ('',9, 12) WHERE Title = N'Crank Arm and Tire Maintenance'; GO SELECT DocumentSummary FROM Production.Document WHERE Title = N'Crank Arm and Tire Maintenance'; GO
T. Использование инструкции UPDATE с функцией OPENROWSET для изменения столбца типа varbinary(max)
В следующем примере существующий образ в столбце типа varbinary(max) заменяется новым образом. Для загрузки образа в столбец используется функция OPENROWSET с параметром BULK. В этом примере предполагается, что по заданному пути существует файл с именем Tires.jpg .
USE AdventureWorks2022; GO UPDATE Production.ProductPhoto SET ThumbNailPhoto = ( SELECT * FROM OPENROWSET(BULK 'c:Tires.jpg', SINGLE_BLOB) AS x ) WHERE ProductPhotoID = 1; GO
Ф. Использование UPDATE для изменения данных FILESTREAM
В следующем примере инструкция UPDATE используется для изменения данных в файлах файловой системы. Не рекомендуется использовать этот метод для потоковой передачи больших объемов данных в файл. Используйте соответствующие интерфейсы Win32. В следующем примере любой текст в записи файла заменяется текстом Xray 1 . Дополнительные сведения см. в разделе FILESTREAM (SQL Server).
UPDATE Archive.dbo.Records SET [Chart] = CAST('Xray 1' as VARBINARY(max)) WHERE [SerialNumber] = 2;
Обновление определяемых пользователем типов данных
В следующих примерах изменяются значения в столбцах определяемых пользователем типов данных CLR. Описываются три метода. Дополнительные сведения об определяемых пользователем столбцах см. в разделе Определяемые пользователем типы данных CLR.
V. Использование системных типов данных
Определяемый пользователем тип можно обновить путем предоставления значения в типе системных данных SQL Server при поддержке определяемым пользователем типа явного или неявного преобразования из этого типа. Следующий пример демонстрирует, как обновить значение в столбце определяемого пользователем типа Point путем явного преобразования строки.
UPDATE dbo.Cities SET Location = CONVERT(Point, '12.3:46.2') WHERE Name = 'Anchorage';
Ц. Вызов метода
Определяемый пользователем тип можно обновить путем вызова метода, отмеченного в качестве мутатора определяемого пользователем типа, для выполнения обновления. Следующий пример вызывает метод мутатора типа Point с именем SetXY . Это обновляет состояние экземпляра типа.
UPDATE dbo.Cities SET Location.SetXY(23.5, 23.5) WHERE Name = 'Anchorage';
X. Изменение значения свойства или элемента данных
Определяемый пользователем тип можно обновить путем изменения значения зарегистрированного свойства или общедоступного элемента данных определяемого пользователем типа. Выражение, предоставляющее значение, должно допускать неявное преобразование в тип свойства. В следующем примере изменяется значение свойства X определяемого пользователем типа Point .
UPDATE dbo.Cities SET Location.X = 23.5 WHERE Name = 'Anchorage';
Переопределение поведения по умолчанию оптимизатора запросов с помощью подсказок
Примеры в этом разделе описывают использование табличных подсказок и подсказок в запросах для временного переопределения поведения оптимизатора запросов при обработке инструкции UPDATE.
Поскольку оптимизатор запросов SQL Server обычно выбирает наилучший план выполнения запроса, подсказки рекомендуется использовать только опытным разработчикам и администраторам баз данных в качестве последнего средства.
Ш. Задание табличной подсказки
В следующем примере задается табличное указание TABLOCK. Эта подсказка указывает, что на таблицу Production.Product накладывается совмещаемая блокировка, удерживаемая до завершения инструкции UPDATE.
USE AdventureWorks2022; GO UPDATE Production.Product WITH (TABLOCK) SET ListPrice = ListPrice * 1.10 WHERE ProductNumber LIKE 'BK-%'; GO
Z. Задание подсказки в запросе
В следующем примере задается указание запроса OPTIMIZE FOR (@variable) в инструкции UPDATE. Эта подсказка указывает на необходимость использования оптимизатором запросов при компиляции и оптимизации запросов конкретного значения локальной переменной. Значение используется только в процессе оптимизации запроса, но не в процессе выполнения.
USE AdventureWorks2022; GO CREATE PROCEDURE Production.uspProductUpdate @Product NVARCHAR(25) AS SET NOCOUNT ON; UPDATE Production.Product SET ListPrice = ListPrice * 1.10 WHERE ProductNumber LIKE @Product OPTION (OPTIMIZE FOR (@Product = 'BK-%') ); GO -- Execute the stored procedure EXEC Production.uspProductUpdate 'BK-%';
Сбор результатов выполнения инструкции UPDATE
Примеры в этом разделе описывают использование предложения OUTPUT для возврата данных для всех строк, изменившихся в результате выполнения инструкции UPDATE, либо выражений на основе этих данных. Эти результаты могут быть возвращены приложению, например для вывода подтверждающих сообщений, архивирования и т. п.
AA. Использование инструкции UPDATE с предложением OUTPUT
В следующем примере значения в столбце VacationHours в Employee изменяются на 25 % для сотрудников, у которых менее 10 часов отпуска, а в столбец ModifiedDate заносится текущая дата. Предложение OUTPUT возвращает значение VacationHours , существующее до применения инструкции UPDATE в столбце deleted.VacationHours , и обновленное значение в столбце inserted.VacationHours к табличной переменной @MyTableVar .
Две следующие инструкции SELECT возвращают значения в табличную переменную @MyTableVar , а результаты операции обновления — в таблицу Employee . Дополнительные примеры использования предложения OUTPUT см. в статье Предложение OUTPUT (Transact-SQL).
USE AdventureWorks2022; GO --Display the initial data of the table to be updated. SELECT BusinessEntityID, VacationHours, ModifiedDate, HireDate FROM HumanResources.Employee WHERE VacationHours < 10 GO DECLARE @MyTableVar TABLE ( EmpID int NOT NULL, OldVacationHours smallint, NewVacationHours smallint, ModifiedDate datetime); UPDATE HumanResources.Employee SET VacationHours = VacationHours * 1.25, ModifiedDate = GETDATE() OUTPUT inserted.BusinessEntityID, deleted.VacationHours, inserted.VacationHours, inserted.ModifiedDate INTO @MyTableVar WHERE VacationHours < 10 --Display the result set of the table variable. SELECT EmpID, OldVacationHours , NewVacationHours, ModifiedDate FROM @MyTableVar; GO --Display the result set of the table. SELECT BusinessEntityID, VacationHours, ModifiedDate, HireDate FROM HumanResources.Employee WHERE VacationHours < 10 GO
Использование инструкции UPDATE в других инструкциях
В примерах в этом разделе описывается использование UPDATE в других инструкциях.
АБ. Использование UPDATE в хранимой процедуре
В следующем примере инструкция UPDATE используется в хранимой процедуре. Процедура принимает один входной параметр @NewHours и один выходной параметр @RowCount . Значение параметра @NewHours используется в инструкции UPDATE для обновления столбца VacationHours в таблице HumanResources.Employee . Выходной параметр @RowCount используется для возврата значения числа задействованных строк в локальную переменную. Выражение CASE используется в предложении SET для условного определения значения, которое задано для столбца VacationHours . Если для сотрудника применяется почасовая ставка оплаты ( SalariedFlag = 0), то в столбце VacationHours устанавливается текущее количество часов плюс значение, заданное в @NewHours . В противном случае в столбце VacationHours указывается значение, заданное в @NewHours .
USE AdventureWorks2022; GO CREATE PROCEDURE HumanResources.Update_VacationHours @NewHours SMALLINT AS SET NOCOUNT ON; UPDATE HumanResources.Employee SET VacationHours = ( CASE WHEN SalariedFlag = 0 THEN VacationHours + @NewHours ELSE @NewHours END ) WHERE CurrentFlag = 1; GO EXEC HumanResources.Update_VacationHours 40;
АВ. Использование UPDATE в блоке TRY. CATCH
В следующем примере инструкция UPDATE используется в блоке TRY. CATCH для обработки ошибок выполнения, которые могут возникнуть во время операции обновления.
USE AdventureWorks2022; GO BEGIN TRANSACTION; BEGIN TRY -- Intentionally generate a constraint violation error. UPDATE HumanResources.Department SET Name = N'MyNewName' WHERE DepartmentID BETWEEN 1 AND 2; END TRY BEGIN CATCH SELECT ERROR_NUMBER() AS ErrorNumber ,ERROR_SEVERITY() AS ErrorSeverity ,ERROR_STATE() AS ErrorState ,ERROR_PROCEDURE() AS ErrorProcedure ,ERROR_LINE() AS ErrorLine ,ERROR_MESSAGE() AS ErrorMessage; IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION; END CATCH; IF @@TRANCOUNT > 0 COMMIT TRANSACTION; GO
Примеры: Azure Synapse Analytics и Система платформы аналитики (PDW)
АГ. Использование простой инструкции UPDATE
В следующем примере показано, как могут быть обработаны все строки, если не использовать предложение WHERE для указания обновляемой строки или строк.
Происходит обновление значений в столбцах EndDate и CurrentFlag для всех строк в таблице DimEmployee .
-- Uses AdventureWorks UPDATE DimEmployee SET EndDate = '2010-12-31', CurrentFlag='False';
В инструкции UPDATE можно также использовать вычисляемые значения. В следующем примере удваивается значение столбца ListPrice для всех строк в таблице Product .
-- Uses AdventureWorks UPDATE DimEmployee SET BaseRate = BaseRate * 2;
АД. Использование инструкции UPDATE с предложением WHERE
В следующем примере предложение WHERE используется для указания строк, которые необходимо обновить.
-- Uses AdventureWorks UPDATE DimEmployee SET FirstName = 'Gail' WHERE EmployeeKey = 500;
АЕ. Использование инструкции UPDATE с меткой
В следующем примере показано использование LABEL с инструкцией UPDATE.
-- Uses AdventureWorks UPDATE DimProduct SET ProductSubcategoryKey = 2 WHERE ProductKey = 313 OPTION (LABEL = N'label1');
АЖ. Использование инструкции UPDATE с данными из другой таблицы
В этом примере создается таблица для хранения итогов продаж по годам. Обновляются итоги продаж за 2004 год с помощью инструкции SELECT в таблице FactInternetSales.
-- Uses AdventureWorks CREATE TABLE YearlyTotalSales ( YearlySalesAmount MONEY NOT NULL, Year SMALLINT NOT NULL ) WITH ( DISTRIBUTION = REPLICATE ); INSERT INTO YearlyTotalSales VALUES (0, 2004); INSERT INTO YearlyTotalSales VALUES (0, 2005); INSERT INTO YearlyTotalSales VALUES (0, 2006); UPDATE YearlyTotalSales SET YearlySalesAmount= (SELECT SUM(SalesAmount) FROM FactInternetSales WHERE OrderDateKey >=20040000 AND OrderDateKey < 20050000) WHERE Year=2004; SELECT * FROM YearlyTotalSales;
АЗ. Соединение ANSI для инструкций обновления
В этом примере показано, как обновить данные на основе результатов соединения с другой таблицей.
CREATE TABLE dbo.Table1 (ColA INT NOT NULL, ColB DECIMAL(10,3) NOT NULL); GO CREATE TABLE dbo.Table2 (ColA INT NOT NULL, ColB DECIMAL(10,3) NOT NULL); GO INSERT INTO dbo.Table1 VALUES(1, 10.0); INSERT INTO dbo.Table2 VALUES(1, 0.0); GO UPDATE dbo.Table2 SET dbo.Table2.ColB = dbo.Table2.ColB + dbo.Table1.ColB FROM dbo.Table2 INNER JOIN dbo.Table1 ON (dbo.Table2.ColA = dbo.Table1.ColA); GO SELECT ColA, ColB FROM dbo.Table2; GO
Update в SQL

Обновление данных в таблицах SQL – одна из базовых операций, с которой предстоит столкнуться пользователю при работе с СУБД MySQL. В качестве обновления (update) подразумевается изменение значений в ранее созданных и на текущий момент существующих записях таблицы. Возможно несколько вариантов реализации:
- изменение значений полей в группе строк;
- корректировка поля для отдельной строчки.
Чтобы уметь работать с облачными и локальными базами данных, пользователям необходимо изучить синтаксис SQL-команд. Далее предстоит рассмотреть основы обновления данных в заданной таблице. Необходимо изучить различные варианты применения update в MySQL. Эта информация будет особо полезна новичкам, но и опытным пользователям она тоже пригодится.
SQL и MySQL
Перед изучением табличных обновлений необходимо понять, что собой представляют MySQL и SQL. Связано это с тем, что новички не всегда знают, с чем им предстоит работать.
SQL – язык запросов. Стандарт для работы с таблицами в базах данных. Его можно использовать не только для обновления, но и для других операций. Примеры – выборка, удаление. Язык структурированных запросов позволяет работать с большим объемом информации. Происходят соответствующие операции в специальных средах. Они называются «системы управления БД».
MySQL – это и есть СУБД. Представляет собой свободную реляционную систему управления БД. Это – наиболее распространенный продукт для малого и среднего бизнеса. В основном используется в качестве отдельного сервера. К нему обращаются локальные и удаленные клиенты.
В официальный дистрибутив MySQL включена собственная библиотека для работы внутреннего сервера. Вместе с ней удастся подключать к СУБД автономные приложения и программы.
Задачи SQL
Задачами SQL-запросов (queries) являются такие операции как:
- Извлечение запрашиваемых сведений из ячеек таблиц баз данных. Происходит это через запрос, отправляемый пользователем.
- Операции с данными. Сюда можно отнести добавление новых компонентов в таблицу, обновление, удаление, сортировку.
- Идентификация информации из БД. Речь идет об определении отдельно взятых компонентов. Пример – числа в тесте используются в качестве целых чисел для дальнейшей обработки.
- Управление имеющимися информационными таблицами.
- Защита и шифрование таблиц.
Синтаксис SQL делится на несколько частей: для решение семантических задач, для непосредственной организации управления информацией в БД и для выдачи пользователям прав на отдельные единицы данных.
Форма записи обновления
Далее предстоит рассмотреть особенности обновления данных при помощи SQL запросов. Для этого нужно изучить специальный оператор, а также форму его представления.
Ключевой оператор обновления в SQL – update. Обновить таблицу удастся последовательно от первой до последней строчки по порядку. В зависимости от типа обновления в MySQL нужно выделить два синтаксиса для update в SQL. Первый вариант используется для работы с одной таблицей, второй – для нескольких.
Одна таблица
В случае, когда необходимо обновить информацию в одной таблице, рекомендуется использовать следующую форму записи:
Обязательным параметром здесь служит только SET assignment_list. Он указывает на то, какие столбцы нужно изменить, а также способ внесения изменений.
К необязательным параметрам в операторе update относят:
- Low_Priority. Если он указан, то обновление будет отложено до тех пор, пока другой клиент не решит посмотреть информацию в таблице.
- Ignore – сценарий, который не прерывает выполнение update from даже при возникновении ошибок. Если появляются дубликаты в столбце с уникальным ключом, то строки не обновляются.
- Where where_condition – оператор, задающий условия обновления данных. Если здесь нет никаких параметров, update будет применяться для всех строк в указанной таблице.
- Order by. Этим выражением устанавливается сортировка. Строки будут обновляться в заданном порядке.
- Limit row_count – ограничение на количество обновляемых strings. Считаться будут все строки, попадающие под условие were, независимо от факта внесения в них тех или иных изменений.
Это – базовая форма представления оператора update в MySQL. Она применяется только для одной таблицы.
Несколько таблиц
Если же их несколько, при работе с Microsoft SQL Server будет использоваться другая форма записи. Ее syntax выглядит так:
Table references – список tables, с которыми будет применяться update set where/select. Изменения осуществляются так, как написано в assignment_list.
Limit и Order by при желании обновить данные сразу в нескольких таблицах, нельзя. Остальные параметры (where, ignore и low_priority) не являются обязательными. Они работают точно также, как и в случае с одной табличкой БД.
Подготовка примера
Чтобы понять принцип функционирования select from update в MySQL Server, предстоит рассмотреть возможные операции на наглядных примерах (examples). Они будут базироваться на заранее подготовленной БД. Она включает в себя информацию о книжном магазине. Поддерживает несколько табличных хранилищ:
Сначала необходимо воспользоваться операторами create table, а также insert into. Они помогут создать author, genre, book и sales.
Получится таблица book:
Здесь такие столбцы:
- book_id – уникальный идентификатор для каждой книжки;
- title – название;
- author_id – идентификатор автора (внешний ключ);
- genre_id – жанр (внешний ключ);
- price – стоимость одного книжного экземпляра;
- amount – количество книжек на складе.
Таблицы genres и author:
А так выглядит sales:
В ней каждая колонка отвечает соответственно за следующие параметры:
- id – уникальный идентификатор;
- book_id – идентификатор книги из таблицы book (внешний ключ);
- count – сколько книг были куплены;
- cost – общая стоимость.
На основе этих таблиц предстоит рассматривать различные варианты использования запросов update в MS Server.
Все строки
Update служит условием обновления всей заданной базы. Для этого его необходимо использовать без параметра where. Пример – в книжном магазине организована акция типа «все за 500». Для отображения этой ситуации у всех книг должна быть фиксированная цена на отметке 500 рублей:
Выглядит это так:
Если попытаться присвоить значения столбца, которые уже находятся в нем, в MySQL ничего не произойдет. Система заметит это и проигнорирует.
При попытке использования значения NULL столбцу, при создании которого было указано NOT NULL, запрос вернет ошибку:
При указании параметра ignore в команде update значение будет изменено на значение по умолчанию. Оно у каждого типа устанавливается свое:
- 0 – для числовых;
- «» — для символьных;
- «нулевое» — для дат.
Это – только один вариант использования update. Он является наиболее простым.
Строки с условием
Изменение строки (string) обычно используется относительно конкретного поля. Полностью обновлять данные в БД требуется крайне редко.
Для изменения записей для одного или нескольких полей команда update используется при условии where. Пример – распродажа книг, который осталось менее 5 штук. Для этого используется такая команда:
Результат обновленной таблички (updated table):
Здесь хорошо заметны изменения. Они вступили относительно Dead Souls и Iliad.
Значения с выражением
Следующий вариант применения update set select – это обновление с заданным выражением. Пример – в магазине проводится акция. Она распространяется на книги русских писателей. Скидка составит 15%.
Для реализации задачи необходимо использовать запрос (query) такого типа:
- В таблице имеются всего два русский писателя. Они имеют ID 1 и 3.
- Обновление значений в заданном образце происходит в определенном порядке – слева направо.
Такой запрос сначала увеличит значение amount на единицу, а после – удвоит его:
Теперь ясно, как организовывать update таблицы SQL с условием-выражением.
С Default
Значение строк (records) может быть изменено на значение по умолчанию. Оно будет задаваться при создании или изменении tables. Чтобы выяснить, какие значения в табличке используются по умолчанию, необходимо выполнить специальную команду. Ей служит запрос:
На экране появится такой результат:
Теперь необходимо заменить значения каждого поля amount на DEFAULT. В этом поможет запись update set select:
Изучаемая команда может применяться иначе. Пример – сразу для нескольких столбцов.
Несколько сразу
Один запрос select from update может помочь, когда требуется обновить не одно поле, а несколько. Выглядит это так:
Здесь происходит замена стоимости и количества у строк, со значениями book_id меньше 4.
Ограничения
Еще один пример использования update – это установление ограничения строк при выводе результатов. Для этого необходимо задействовать setting LIMIT.
Здесь происходит update первой строчки. LIMIT не используется для обновления N полей. В результате запроса происходит обработка первых N-строк, которые подойдут под условие Where.
Обновление нескольких таблиц
Далее будут рассмотрены примеры update для нескольких таблиц. Это – самый простой вариант из всех существующих:
Возможны разные варианты использования изучаемой команды. Иногда корректировки устанавливаются путем объединения нескольких табличных компонентов или на основе информации из других элементов БД. Далее все эти варианты будут рассмотрены более подробно.
Объединение Inner Join
Команду (operator) Update можно использовать для обновления информации путем объединения нескольких компонентов БД. Самый простой вариант – это применение для updates INNER JOIN.
Указывает INNER не обязательно. Связано это с тем, что при использовании обновления данных параметр используется по умолчанию.
Объединение «слева»
Еще один вариант объединения – это Left Join. Он применяется с update set select, если требуется именно «левое объединение». Указывать его полностью обязательно.
Пример – изменение на складе количества книг после их непосредственной покупки:
Если магазин продал 3 книжки «Анна Каренина» и одну – Dead Souls, запрос будет выглядеть так:
Если не использовать left join в заданном примере запроса SQL update, на экране появится ошибка. Связано это с тем, что поле amount не может быть отрицательным. При использовании параметра ignore появится следующий результат:
Здесь каждое поле будет уменьшено на 3. Результат будет ошибочным.
Условные операторы
Update set select (обновление) может производиться через условные операторы:
Case используется для проверки истинности выбора условий. В зависимости от полученного результата вернут один из нескольких вариантов значений. Синтаксис при работает с таким update from окажется таким:
Результат в example:
При помощи функции IF каждый раз в зависимости от условного выражения будет возвращаться одно из двух значений. Пример – если у книги жанр 4, ее стоимость уменьшается на 200 рублей. В противном случае ценник остается прежним:
Через IFNULL оператор update проверит значение выражения. Если оно NULL, возвращается определенный «параметр». В противном случае – самое выражение. Пусть одно значение в заданной таблице окажется нулевым:
Оно должно быть заменено на 0. Соответствующий запрос должен выглядеть так:
При помощи COALESCE можно указывать несколько значений, которые может принимать функция. Работает подобно IFNULL.
С сортировкой
Select from и update – базовые операции для работы с таблицами. Их обновление возможно. Данный процесс помогает в ситуациях, когда изменения вступают в силу относительно поля с уникальным ключом.
Если захочется сдвинуть id на единицу, изменив первую строчку, получится две строки, у которых Это вызовет ошибку. При добавлении order by и проведении обновления с конца, запрос будет успешно выполнен:
Но и это еще не все. Можно использовать select from и update для обновления на основе информации из других таблиц.
На основе других таблиц
В условии Where можно использовать вложенные команды – from и select. Вот – пример, в котором сначала sets индикатор жанра “Epic poetry”, а затем на основе соответствующего значения происходит отбор строки для обновления:
Чтобы выбрать значения, которые требуется изменить, используется запрос:
Требуется изменить стоимость всех книг, которых менее 5 штук на складе, на минимальную сумму продажи. Она будет равна 480. Обновить таблицу из самой себя не получится. Поэтому придется объединить компоненты между собой:
Все это – основы работы с SQL. Лучше понимать запросы, primary key, tables и даже изучить T-SQL с нуля помогут специальные дистанционные компьютерные курсы. Они прекрасно совмещаются с карьерой и учебой, а в конце выдается электронный сертификат, подтверждающий спектр приобретенных навыков и умений.
