Sql как изменить запись в таблице: SQL запрос на изменение данных в таблице БД

Команда UPDATE – редактирование записей в базе данных

Команда UPDATE редактирует записи в базе данных.

Какие записи для редактирования
задаются с помощью команды WHERE.

Команда WHERE не является обязательной, если ее не указать –
будут обновлены все записи в таблице. Будьте внимательны – так случайно можно
уничтожить все данные.

См. также команды
SELECT,
INSERT,
DELETE,
которые отвечают за получение, вставку и удаление записей.

Синтаксис

UPDATE имя_таблицы SET поле1=значение1, поле2=значение2, поле3=значение3...
	WHERE условие_по_которому_следует_выбрать_строки

Примеры

Все примеры будут по этой таблице workers, если не сказано иное:

id
айди
name
имя
age
возраст
salary
зарплата
1 Дима 23 400
2 Петя 24 500
3 Вася 25 600

Пример

В данном примере работнику с id, равным 1 (то есть Диме), устанавливается возраст 30
и зарплата 1000:

UPDATE workers SET age=30, salary=1000 WHERE id=1

Таблица workers станет выглядеть так:

id
айди
name
имя
age
возраст
salary
зарплата
1 Дима 30 1000
2 Петя 24 500
3 Вася 25 600

Пример

В данном примере работнику с id, равным 1 (то есть Диме), устанавливается возраст 30:

UPDATE workers SET age=30 WHERE id=1

Таблица workers станет выглядеть так:

id
айди
name
имя
age
возраст
salary
зарплата
1 Дима 30 400
2 Петя 24 500
3 Вася 25 600

Пример

В данном примере работнику Пете устанавливается новое имя Коля:

UPDATE workers SET name='Коля' WHERE name='Петя'

Таблица workers станет выглядеть так:

id
айди
name
имя
age
возраст
salary
зарплата
1 Дима 23 400
2 Коля 24 500
3 Вася 25 600

Пример

В данном примере всем работникам устанавливается зарплата 1000
(так как не задано WHERE – наш запрос обновит все записи):

UPDATE workers SET salary=1000

Таблица workers станет выглядеть так:

id
айди
name
имя
age
возраст
salary
зарплата
1 Дима 23 1000
2 Петя 24 1000
3 Вася 25 1000

← Предыдущая страница
Следующая страница →

если есть изменить запись если нет то добавить запись

 
redlord
 
(2005-07-17 21:26)
[0]

всем привет
народ помогите составить запрос sql к базе mssql
имеется таблица с тремя полями f1 f2 f3 записи в f1 уникальны
мне нужно добавлять строку тока в том случае если значение из добавляемой строки в поле f1 не совпадает ни с одним значение поля F1 уже имеющихся в таблице. а если совпадают то поменять у уже имеюжейся записи значение поля f2


 
Desdechado ©
 
(2005-07-17 22:56)
[1]

begin
 insert…
exception
 update
end;

можно оформить как кодовый блок в SQL.Text
при условии, что в структуре БД правильно прописаны CONSTRAINTS


 
evvcom ©
 
(2005-07-18 09:24)
[2]

Раньше в MSSQL exception не было, сейчас на скору руку тоже не нашел, так что мой вариант таков:
update …
if @@ROWCOUNT = 0
 insert …


 
Anatoly Podgoretsky ©
 
(2005-07-18 09:33)
[3]

В MSSQL есть триггер INSTEAD OF


 
MOA ©
 
(2005-07-18 09:36)
[4]

Поскольку поле f1 – первичный ключ => индексировано, прозрачнее будет (я бы так и сделал)
IF EXISTS(SELECT * FROM t WHERE f1=. .)
UPDATE ….
ELSE
INSERT ….
Удачи!


 
Fay ©
 
(2005-07-18 09:38)
[5]

2 Anatoly Podgoretsky ©   (18.07.05 9:33) [3]
А в Oracle есть BEFORE. И чего, как это поможет?


 
Ega23 ©
 
(2005-07-18 09:38)
[6]


Declare @X int
Set @X=-1
Select @X=1 from Table1 where F1=...
if @X=-1
begin
 Insert
end
else
begin
 Update
end


 
Fay ©
 
(2005-07-18 09:40)
[7]

2 MOA ©   (18.07.05 9:36) [4]
Удача явно потребуется, т.к. между
IF EXISTS(SELECT * FROM t WHERE f1=. .)
и
UPDATE ....
ELSE
INSERT ....

запись может быть удалена/добавлена.


 
MOA ©
 
(2005-07-18 09:45)
[8]

2Fay ©
Согласен, на этот аспект внимания не обратил :(.


 
evvcom ©
 
(2005-07-18 09:46)
[9]


> MOA ©   (18.07.05 09:36) [4]
> Ega23 ©   (18.07.05 09:38) [6]

Ваши запросы в случае update делают 2 скана таблицы. Зачем, если можно обойтись одним?


 
Fay ©
 
(2005-07-18 09:49)
[10]

2 evvcom ©   (18.07.05 9:46) [9]
Внимательно жду(ждём) подробностей.


 
Ega23 ©
 
(2005-07-18 09:52)
[11]

2 Fay ©   (18. 07.05 09:49) [10]

Ну формально-то он прав.
В первый раз ищет exists (в моём случае F1=@F1).
Во второй – ищет по where.
Если взять крайни случай, что интересующая нас запись самая последнеяя – получается действительно 2 скана.
Но: если это поле индексировано, то по какому алгоритму будет искаться F1=@F1?


 
Fay ©
 
(2005-07-18 09:53)
[12]

2 Ega23 ©   (18.07.05 9:52) [11]
index seek


 
Anatoly Podgoretsky ©
 
(2005-07-18 09:56)
[13]

Fay ©   (18.07.05 09:38) [5]
Ни чем, вопрос про MS SQL


 
ЮЮ ©
 
(2005-07-18 09:58)
[14]

>Удача явно потребуется, т. к. между
>IF EXISTS(SELECT * FROM t WHERE f1=..)

>UPDATE ….
>запись может быть удалена/добавлена

Если в рамках одной транзакции, а между ними нет закрытия ожной и старта новой транзакции, то никуда она не денется


 
Fay ©
 
(2005-07-18 10:00)
[15]

2 ЮЮ ©   (18.07.05 9:58) [14]
Денется, ещё как.

2 Anatoly Podgoretsky ©   (18.07.05 9:56) [13]
А что Вы имели ввиду, говоря про наличие таких триггеров?


 
Fay ©
 
(2005-07-18 10:00)
[16]

2 ЮЮ ©   (18.07.05 9:58) [14]
… или появится


 
Anatoly Podgoretsky ©
 
(2005-07-18 10:01)
[17]

Она естественно никуда не денется, но может оказаться добавленой в промежутке между SELECT и INSERT


 
evvcom ©
 
(2005-07-18 10:06)
[18]


> Внимательно жду(ждём) подробностей.

А чего непонятно? В обоих случаях используется сначала select (1-ый скан), потом update (2-ой скан). А индексы тут не при чем, они на количество сканов никак не влияют. На продолжительность (объем перебора и т.п.) да, но на количество…


 
Fay ©
 
(2005-07-18 10:17)
[19]

2 evvcom ©   (18.07.05 10:06) [18]
Честно говоря, я ждал Вышего решения задачи, а не проповеди.

2 ЮЮ ©   (18.07.05 9:58) [14]
Открываем QA. В одном окне пишем
use pubs
go
if object_id("QWE") is not null
 drop table QWE
go
create table QWE(
CODE int not null,
NAME varchar(32) collate SQL_Latin1_General_CP1251_CI_AS not null,
constraint PK_QWE primary key nonclustered(CODE),
constraint UNQ_QWE_NAME unique(NAME)
)
go

insert into QWE (CODE, NAME) values (1, “1”)
insert into QWE (CODE, NAME) values (2, “2”)
insert into QWE (CODE, NAME) values (3, “3”)
go

declare
 @n int,
 @s varchar(32),
 @dt datetime

select
 @n = 2,
 @s = “Два”,
 @dt = “00:00:05”

begin tran

if exists(select * from QWE where CODE = @n)
 begin
   waitfor delay @dt
   update QWE set NAME = @s where CODE = @n
 end
else
 begin
   waitfor delay @dt
   insert into QWE (CODE, NAME) values (@n, @s)
 end
 select [row count] = @@rowcount
commit tran
go
drop table QWE
, а в другом
use pubs
delete from QWE where CODE = 2

Запускаем сначала 1-й, и пока он думает, 2-й скрипт.
Внимательно смотрим на [row count]


 
Ega23 ©
 
(2005-07-18 10:20)
[20]

2 Fay ©   (18.07.05 10:17) [19]

Ты меня опередил…  :о)


 
evvcom ©
 
(2005-07-18 10:29)
[21]


> Честно говоря, я ждал Вышего решения задачи, а не проповеди

А [2] что такое?


 
MOA ©
 
(2005-07-18 11:02)
[22]

Прошло вот так:

CREATE TABLE [t4] (
[f1] [int] NOT NULL ,
[f2] [int] NULL ,
[f3] [int] NULL ,
CONSTRAINT [PK_t4] PRIMARY KEY  CLUSTERED
(
 [f1]
)  ON [PRIMARY]
) ON [PRIMARY]
GO

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
GO
BEGIN TRANSACTION
IF EXISTS(SELECT * FROM t4 WITH (UPDLOCK) WHERE f1=3)
BEGIN
WAITFOR DELAY “00:00:05”
UPDATE t4 SET f2=223 WHERE f1=3
END
ELSE
BEGIN
WAITFOR DELAY “00:00:05”
INSERT INTO t4 (f1, f2, f3) VALUES (3, 203, 303)
END
COMMIT TRANSACTION
Т. е. с уровнем транзакции SERIALIZABLE и хинтом на экзисте UPDLOCK – всё ждёт как надо кого надо ;).


 
Ega23 ©
 
(2005-07-18 11:03)
[23]

2 evvcom ©   (18.07.05 10:29) [21]
А [2] что такое?

В [2] ты привязываешься к глобальной переменной @@ROWCOUNT, что может быть чревато последствиями. Нехорошими.


 
ЮЮ ©
 
(2005-07-18 11:14)
[24]

>В [2] ты привязываешься к глобальной переменной @@ROWCOUNT

Может тогда и @@ERROR небезопасно смотреть, ведь там может оказаться чужая ошибка 🙂
if @@ROWCOUNT = 0 – впримере из BOL стоит


 
ЮЮ ©
 
(2005-07-18 11:15)
[25]

Честно говоря, хотелось бы автора услушать, откуда такое желание возникло, точнее откуда это f1 взялось.

Если из этой же базы, то к чему такие извращения. Ведь если f1 определен, то запись есть и её надо редактировать. Даже если её уже не стало, то зачем вставлять, если её только что кто-то удалил? А если запись новая, то откуда f1 на клиенте? Его должен тогда сервер определить, ибо два клиента по одному и тому же алгоритму получат одно и тоже значение для новой записи, а это не лучше, чем в случае Fay ©   (18.07.05 10:17) [19]

Если же это внешние данные, то ситуация описанная в [19]
тоже притянута за уши, т.к. если из двух разных пакетов путаются вставить разные записи (разные f2 или f3 для одинакового f1), то это уже ошибка, независимо от поведения сервера, а если одинаковые, то не важно из какого пакета она добавится. А добавление 2х записей невозможно ввиду ” f1 уникальны”


 
evvcom ©
 
(2005-07-18 11:15)
[26]


> что может быть чревато последствиями. Нехорошими

Сейчас в хелпе этого не увидел, но раньше читал, что если читать из @@ROWCOUNT сразу же за селектом, апдейтом и т.п., то это гарантирует, что она покажет именно нужное значение. А иначе зачем было мелкомягким вводить такую переменную, если ей нельзя доверять на 100%?


 
evvcom ©
 
(2005-07-18 11:19)
[27]

А [6], кстати, может быть чревато последствиями. Нехорошими
еще с большей вероятностью. Имхо.


 
Fay ©
 
(2005-07-18 11:34)
[28]

2 MOA ©   (18.07.05 11:02) [22]
INSERT-ом проверял?


 
evvcom ©
 
(2005-07-18 11:38)
[29]


> WAITFOR DELAY “00:00:05”

А это зачем? Искусственные тормоза? Делай [2] и хватит ерундой заниматься с кучей лишних запросов, да еще искусственных задержек.


 
MOA ©
 
(2005-07-18 11:43)
[30]

>Fay ©   (18.07.05 11:34) [28]
>INSERT-ом проверял?
Угу. Во втором сеансе запускалось почти то же:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
GO
BEGIN TRANSACTION
IF EXISTS(SELECT * FROM t4 WITH (UPDLOCK) WHERE f1=3)
BEGIN
WAITFOR DELAY "00:00:05"
UPDATE t4 SET f2=2223 WHERE f1=3
END
ELSE
BEGIN
WAITFOR DELAY "00:00:05"
INSERT INTO t4 (f1, f2, f3) VALUES (3, 2003, 3003)
END
COMMIT TRANSACTION

Результат – всё как надо, ждёт инсерта с первого сеанса, потом апдейтит (записи с f1=3 в таблице первоначально нет).


 
MOA ©
 
(2005-07-18 11:45)
[31]

>evvcom ©   (18. 07.05 11:38) [29]
>> WAITFOR DELAY “00:00:05”
>А это зачем?
А это чтобы наглядно проверить (чтобы кнопулю успеть нажать во втором сеансе), что транзакции отрабатывают как надо – моделируем так сказать, ситуацию, когда два процесса проверили – и оба получили, что записи нет – оба пытаются вставить, что нехорошо :).


 
Fay ©
 
(2005-07-18 11:46)
[32]

Сам проверил – всё ОК.
Остаётся только тщательней следить за захватом ресурсов воизбежание deadlock-ов.


 
redlord
 
(2005-07-18 23:51)
[33]

очен жалко что позно зашол на ветку да и сечас уже поздно а завтра обязательно изучу все посты
спасибо всем откликнувшимся


Запрос обновления SQL для обновления нескольких столбцов и таблиц в MySQL

Команда обновления в SQL используется для изменения любой записи в таблице. Записи должны быть изменены с помощью команды обновления.

Условное обновление является наиболее распространенным типом команды update , используемой в MySQL. Вы можете прочитать команду SQL WHERE перед использованием команды обновления, так как обе они должны использоваться в правильных комбинациях.

Вот одна простая команда, но прежде чем пытаться это сделать, вы должны понять значение этого. Без использования какой-либо команды where (или без использования каких-либо ограничений) команда изменит все записи таблицы.


При необходимости удалите таблицу учащихся с помощью этого запроса.

 СТОЛ ДЛЯ УЧЕНИКОВ 

Вы можете восстановить таблицу с данными, снова используя дамп SQL.

Обновите все записи, изменив class на Five .

  ОБНОВЛЕНИЕ  студент  НАБОР  

Эта команда изменит все записи таблицы student и изменит все поля класса на Five . Это не то, что требуется в обычных случаях, поэтому мы будем изменять записи в зависимости от некоторых условий. Теперь мы изменим всех учеников класса с четырьмя учениками на пять учеников класса . Наша команда должна выборочно обновить те записи, для которых класс равен четырем и обновит их до пять . Мы будем использовать одно предложение where вместе с командой обновления для обновления записей.

  ОБНОВЛЕНИЕ  студент  НАБОР   ГДЕ  

Связанный учебник
Заменить часть данных
Добавление строковых данных
Количество затронутых строк

Эта команда обновит только те записи, для которых класс равен «Четыре». Таким образом, мы можем выборочно обновлять записи. Теперь давайте перейдем еще на один шаг и выборочно изменим записи на основе некоторого значения в каком-то другом поле. Мы изменим записи, для которых класс равен «Четыре» и оценка больше 70. Мы будем продвигать только тех учеников, которые получили больше или равно 70 баллов.
Возможно, вам придется восстановить исходную таблицу, используя приведенный выше дамп SQL таблицы учеников.

  ОБНОВЛЕНИЕ  студент  НАБОР   ГДЕ  и отметьте >= 70 

Это изменит только те записи, для которых класс = четыре и метка больше или равна 70. Мы добавили два условия, используя И в качестве логического оператора. Таким образом, мы можем продолжить добавлять в запрос дополнительные комбинации И. В зависимости от логического требования к предложению WHERE можно добавить комбинацию ИЛИ для ОБНОВЛЕНИЯ записей.

Обновление нескольких столбцов таблицы

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

7 09073 6 Четыре

0073 50

8

id имя класс социальный наука математика
2 Макс Руин Три 74

85 56 85
3 Арнольд Три 55 40 75
4 Криш Стар 70
5 Джон Майк Четыре 60 80 90
6 Алекс Джон Четыре 55 90 7 8 58

7 Мой Джон Роб Пятый 78 60 70
8 Асруид Пять 85
9 Тес Кры Шесть 78 60 70
10 Большой Джон Четыре 55 40 55

Загрузите дамп SQL этой таблицы в конце этой страницы.

Обновление отметки ученика

Давайте обновим новые оценки для Krish Star ( id = 4)

  ОБНОВЛЕНИЕ  student3  SET  математика=50, социальная=60, естествознание=55  ГДЕ  id=4 

Увеличим оценку Арнольда ( id =3 ) на 5 по всем предметам

  UPDATE  student3  SET  math=math+5, social=social+5, science=science+5  WHERE  id=3 

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

  ОБНОВЛЕНИЕ  студент3  НАБОР  математика = 0, социальная = 0, наука = 0 

Чтобы обновить несколько записей, используйте INSERT… ON DUPLICATE KEY UPDATE

Обновление второй таблицы данными из первой таблицы



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

Таблица оценок учащихся состоит из двух столбцов: s_id хранит идентификатор учащегося, а столбец mark хранит общую оценку учащегося.
Сначала изменим общую оценку всех студентов на ноль.

  ОБНОВЛЕНИЕ  student3_total  SET  отметка=0 

Теперь давайте обновим этот столбец оценок таблицы student3_total суммой оценок по предметам таблицы student3. Вот запрос.

 update student3_total,student3 SET mark= (математика+общественные+естественные науки)
  ГДЕ s_id=id 

Использование левого соединения

 ОБНОВЛЕНИЕ student3_total ЛЕВОЕ ПРИСОЕДИНЕНИЕ student3 ON s_id=id
SET отметка= (математика+социальные+науки) 

Подробнее о ЛЕВОМ СОЕДИНЕНИИ

Использование внутреннего соединения

  ОБНОВЛЕНИЕ  student3_total  ВНУТРЕННЕЕ СОЕДИНЕНИЕ  student3  ON  s_id=id  SET 
 отметка= (математика+общественные+науки) 

Обновить ту же таблицу со средним значением

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

Вы можете скачать дамп таблицы MySQL с примерами данных здесь.

Суммирование среднего балла каждого ученика.

 обновление student3_avg a
LEFT JOIN (выберите id, sum(social + math + science)/3 как число
ОТ группы student3_avg по id)
 как b на a.id=b.id установить a.average=b.number 

Мы использовали LEFT JOIN, чтобы присоединиться к одной и той же таблице и получить среднюю оценку каждого ученика. Теперь мы будем хранить среднее значение класса для каждого ученика, используя GROUP BY Query.

 обновить student3_avg ЛЕВОЕ СОЕДИНЕНИЕ
(выберите класс, среднее (среднее) как число из
student3_avg группа по классу)
 как b на наборе a.class=b.class a.average_class=b.number 

Обновление с помощью соединения LEFT с использованием более двух таблиц

 ОБНОВЛЕНИЕ таблицы 1 а
LEFT JOIN table2 b на a. ORD_NO=b.ORD_NO
LEFT JOIN table3 c на c.empno=b.empno
установить table1_column = concat (Column1, table2_column3 c.name)
ГДЕ a.column2 > 100 

Обновление поля пароля с использованием шифрования md5

Мы можем обновить поле пароля с помощью шифрования md5. Чтобы сохранить эти данные, мы изменим длину поля на 32 символа. Вот команда для обновления поля пароля новым зашифрованным паролем md5.

 обновить user_mem установить пароль = md5 (пароль) 

Замена части данных поля с помощью команды replace в операторе SQL

Загрузить дамп sql таблицы student3
Загрузить дамп sql таблицы student3_total
Загрузить дамп sql таблицы student3_avg
← Копировать таблицу Обновление нескольких записей с помощью ON DUPLICATE KEY UPDATE →

← Подпишитесь на наш канал YouTube здесь

Эта статья написана командой plus2net.com .
https://www.plus2net.com

plus2net. com

Подробнее об изменении или изменении таблицы, добавлении обновлений или удалении записей в SQL

cm_mehdi

44 24-01-01-01-01-01-01-01-01-01-01-01-01-01-01-01-01-01-01-01

очень хорошо
мурали

03.11.2010

всем привет это очень хороший урок 44 07.06.2010

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

04.10.2011

как вставить более одной строки в sql 2008
пожалуйста, пришлите полный код в asp. net
Larry L

02-03-2014

Я продолжаю получать синтаксические ошибки, используя это. В моем примере я пытаюсь добавить содержимое Field1+Feild2 в Field1.
TableName (имя таблицы)
Field1 = 5
Field2 = 2
Я хочу обновить его так, чтобы в этом примере Field1 = 5+2.
Попытка использовать две строки:
UPDATE ‘TableName’
SET R1= сумма(R1,R1a)

06.05.2021

очень хорошие уроки

Пишите сюда свои комментарии, предложения, ошибки, требования и т.д.

Деталь

Запросы
ВСТАВЛЯТЬ
ОБНОВЛЯТЬ

Совокупные запросы
СРЕДНИЙ (средний)
СУММА
МИН.
МАКС

Видеоруководства по SQL

© 2000-2023 plus2net. com Все права защищены во всех странах мира
Политика конфиденциальности Отказ от ответственности

Как выполнить ОБНОВЛЕНИЕ из инструкции SELECT в SQL Server

В этой статье мы изучим различные методы, которые используются для обновления данных в таблице данными других таблиц. Структура запроса UPDATE from SELECT является основным методом выполнения этих обновлений.

Запрос UPDATE используется для изменения существующей строки или строк в базе данных. Запросы UPDATE могут изменять все строки таблиц, или мы можем ограничить действие оператора обновления для определенных строк с помощью ГДЕ пункт. В основном мы используем постоянные значения для изменения данных, например, следующие структуры.

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

Таблица UPDATE

SET столбец 1 = постоянное_значение1 , столбец 2 =  постоянное_значение2 , столбец N = постоянное_значениеN

Условное обновление 9Оператор 0286 используется для изменения данных, удовлетворяющих условию WHERE .

ОБНОВЛЕНИЕ таблицы

SET col1 = константное_значение1 , col2 =  constant_value2 , colN = константное_значениеN

WHERE col = val

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

Подготовка данных образца

С помощью следующего запроса мы создадим таблицы Persons и AddressList и заполним их синтетическими данными. Эти две таблицы связаны через столбец PersonId , что означает, что в этих двух таблицах значение столбца PersonId представляет одно и то же лицо.

1

2

3

4

5

6

7

8

9

10

11

12

4 5

1 5

16

17

18

19

20

21

22

23

24

25

26

27

28

29

404

30 9004

32

33

34

35

36

37

38

CREATE TABLE dbo.Persons

( PersonId       INT

  PRIMARY KEY IDENTITY(1, 1) NOT NULL,

  PersonName     VARCHAR(100) NULL,

 9004Name NULL,

  PersonPostCode VARCHAR(100) NULL,

  PersonCityName VARCHAR(100) NULL)

 

GO

 

CREATE TABLE  AddressList(

)   1[AddressId, NOTARY ENT]

  [PersonId] [int] NULL,

  [PostCode] [varchar](100) NULL,

  [Город] [varchar](100) NULL)

 

GO

ВСТАВИТЬ В ЛИЦА

(PersonName, PersonLastName )

ЗНАЧЕНИЯ

(N’Salvador’, N’Williams’),

(N’Lawrence’, N’Brown’),

(N’Gilbert’, N’Jones’),

(Н’Эрнест’, Н’Смит’),

(Н’Хорхе’, Н’Джонсон’)

 

GO

INSERT INTO AddressList

(PersonId, PostCode, City)

ЗНАЧЕНИЯ

(1, N’07145′, N’Philadelphia’),

(2, N’68443′, N’New York’),

(3, N’50675′, N’Phoenix’),

(4, N’96573′, N’Chicago’)

 

SELECT * FROM Persons

SELECT * FROM AddressList

ОБНОВЛЕНИЕ из SELECT: Метод соединения

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

В следующем примере мы обновим данные столбцов PersonCityName и PersonPostCode данными столбцов City и PostCode таблицы AdressList .

1

2

3

4

5

6

7

8

ОБНОВЛЕНИЕ В соответствии с

SET

Per.PersonCityName=Addr.City,

Per.PersonPostCode=Addr.PostCode

FROM Persons Per

INNER JOIN

AddressList Addr

ON Per.PersonId = Addr.PersonId

После выполнения обновления из запроса на выборку вывод таблицы Persons будет таким, как показано ниже;

ВЫБЕРИТЕ * ОТ лиц

Попробуем разобраться в приведенном выше коде:

Мы набрали имя таблицы, которое будет обновлено после оператора UPDATE . После ключевого слова SET мы указали имена столбцов для обновления, а также сопоставили их со столбцами таблицы, на которые ссылаются. После предложения FROM мы перепечатали имя таблицы, которое будет обновлено. После предложения INNER JOIN мы указали ссылочную таблицу и присоединили ее к таблице, которую нужно обновить. В дополнение к этому, мы можем указать WHERE и отфильтровать любые столбцы указанной или обновленной таблицы. Мы также можем переписать запрос, используя псевдонимы для таблиц.

1

2

3

4

5

6

7

8

UPDATE Per

SET

    Per.PersonCityName=Addr.City,

    Per.PersonPostCode=Addr.PostCode

FROM Persons Per

INNER0045

AddressList Addr

ON Per.PersonId = Addr.PersonId

Совет по производительности:

Индексы — очень полезные объекты базы данных для повышения производительности запросов в SQL Server. В частности, если мы работаем над производительностью запроса на обновление, мы должны учитывать эту вероятность. Следующий план выполнения иллюстрирует план выполнения предыдущего запроса. Единственное отличие состоит в том, что этот запрос обновил 3 000 000 строк чел. табл. Этот запрос был выполнен в течение 68 секунд.

Мы добавили некластеризованный индекс в таблицу Persons перед обновлением, и добавленный индекс включает столбцы PersonCityName и PersonPostCode в качестве ключа индекса.

Следующий план выполнения демонстрирует план выполнения того же запроса, но этот запрос был выполнен в течение 130 секунд из-за добавленного индекса, в отличие от первого.

Операторы Index Update и Sort потребляют 74% стоимости плана выполнения. Мы видели эту очевидную разницу в производительности одного и того же запроса из-за использования индекса в обновленных столбцах. В результате, если обновленные столбцы используются индексами, как, например, в этом случае, это может отрицательно сказаться на производительности запросов. В частности, нам следует учитывать эту проблему, если мы будем обновлять большое количество строк. Чтобы решить эту проблему, мы можем отключить или удалить индекс перед выполнением запроса на обновление.

С другой стороны, на операторе Sort , виден предупреждающий знак, который указывает на то, что у этого оператора что-то не так. Когда мы наводим указатель мыши на этот оператор, мы можем увидеть детали предупреждения.

Во время выполнения запроса оптимизатор запросов вычисляет необходимое потребление памяти для запроса на основе предполагаемых номеров строк и размера строк. Однако эта оценка потребления может быть ошибочной по ряду причин, и если для запроса требуется больше памяти, чем для оценки, он использует данные tempdb. Этот механизм называется утечкой базы данных tempdb и приводит к потере производительности. Причина этого: память всегда быстрее, чем база данных tempdb, потому что база данных tempdb использует ресурсы диска.

Вы можете прочитать эту фантастическую статью SQL Server 2017: SQL Sort, Spill, Memory and Adaptive Memory Grant Feedback, чтобы узнать больше о проблеме с разливом tempdb.

ОБНОВЛЕНИЕ из SELECT: оператор MERGE

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

Теперь, если мы вернемся к нашей позиции, оператор MERGE можно использовать как альтернативный метод для обновления данных в таблице данными из другой таблицы. В этом методе ссылочную таблицу можно рассматривать как исходную таблицу, а целевую таблицу будет обновлять таблица. Следующий запрос может быть примером этого метода использования.

1

2

3

4

5

6

7

8

9

ОБЪЕДИНИТЬ людей КАК Согласно

ИСПОЛЬЗОВАНИЕ(ВЫБРАТЬ * ИЗ списка адресов) КАК Адрес

ON Addr.PersonID=Per.PersonID

КОГДА СООТВЕТСТВУЕТ ТО

ОБНОВЛЕНИЕ НАБОР

AddrPersonPodeCode=PersonPersonID=Per.PersonID 045

Пер. PersonCityName = Адрес Города;

 

ВЫБРАТЬ * ИЗ лиц

Теперь давайте рассмотрим предыдущее обновление из запроса на выборку построчно.

ОБЪЕДИНЕНИЕ Лица КАК Согласно

Мы ввели таблицу Persons после оператора MERGE , потому что это наша целевая таблица, которую мы хотим обновить, и мы дали ей псевдоним Per , чтобы использовать остальную часть запроса.

USING(SELECT * FROM AddressList) AS Addr

После оператора USING мы указали исходную таблицу.

ON Addr.PersonID=Per.PersonID

С помощью этого синтаксиса определяется условие соединения между целевой и исходной таблицами.

КОГДА СООТВЕТСТВУЕТ ТО

НАБОР ОБНОВЛЕНИЙ Per.PersonPostCode=Addr.PostCode;

В этой последней строке запроса мы выбрали метод манипулирования совпадающими строками. Отдельно для этого запроса мы выбрали метод UPDATE для сопоставленных строк целевой таблицы. Наконец, мы добавили точку с запятой (;), потому что операторы MERGE должны заканчиваться точками с запятой.

ОБНОВЛЕНИЕ из SELECT: метод подзапроса

Подзапрос — это внутренний запрос, который можно использовать внутри операторов DML (SELECT, INSERT, UPDATE и DELETE). Основной характеристикой подзапроса является то, что они могут выполняться только с внешним запросом.

Метод подзапроса — это очень простой и простой способ обновления существующих данных из данных других таблиц. Заметная разница в этом методе заключается в том, что это может быть удобный способ обновить один столбец для таблиц с небольшим количеством строк. Теперь мы выполним следующий запрос, а затем проанализируем его.

UPDATE Persons

SET  Persons.PersonCityName=(SELECT AddressList.PostCode

                          FROM AddressList

                           ГДЕ AddressList.PersonId = Persons.PersonId)

После выполнения обновления из оператора select вывод таблицы будет следующим:

ВЫБЕРИТЕ * ОТ лиц

Как мы видим, Данные столбца PersonCityName таблицы Persons обновлены данными столбца City таблицы AddressList для сопоставленных записей для столбца PersonId .