В тази статия ще разгледаме различните методи за използване на оператора UPDATE от SELECT в SQL Server.
В света на базата данни статичните данни обикновено не се съхраняват. Вместо това той продължава да се променя, когато актуализираме съществуващи данни, архивираме или изтриваме неподходящи данни и др. Например, да приемем, че имате таблица, която съхранява данни за цените на продуктите за вашия портал за пазаруване. Цените на продуктите непрекъснато се променят, тъй като може да предлагате продуктови отстъпки по различно време на клиентите си. В този случай не можете да добавяте нови редове в таблицата, тъй като записът на продукта вече съществува, но от вас се изисква да актуализирате текущите цени за съществуващи продукти.
Тук влиза в действие заявката UPDATE. Заявката UPDATE променя данни в съществуващ ред в базата данни. Можете да актуализирате всички редове в таблицата или да ограничите засегнатите редове за актуализацията, като използвате клаузата WHERE. Обикновено SQL актуализациите се извършват за съществуваща таблица с директна препратка. Например в таблица [служители] изискването трябва да увеличи заплатата на всички активни служители с 10%. В този случай директната препратка SQL заявка ще бъде:
Актуализиране на набора за служители [заплата]=заплата + (заплата * 10 / 100) където [активен]=1
Да предположим, че имате друга таблица [Адрес], която съхранява местоположенията на служителите и от вас се изисква да актуализирате таблицата [Служител] въз основа на наличните данни в таблицата [Адрес]. Как актуализирате данните в таблицата [Employee]?
За щастие има решение - UPDATE от оператор SELECT. В следващия раздел разглеждаме различни начини за извършване на актуализации с помощта на оператор SELECT. Например таблицата [Служител] има стойности NULL за колони – [PostCode] и [City] на следващата екранна снимка. Таблицата [Address] съдържа стойности и за двете колони [PostCode] и [City].
Метод 1:АКТУАЛИЗИРАНЕ от SELECT:Метод на присъединяване
Този метод използва SQL Joins за препратка към вторичната таблица, която съдържа стойности, които трябва да бъдат актуализирани. Следователно целевата таблица се актуализира с данните от референтните колони за посочените условия.
В този случай е доста лесно да използвате оператора UPDATE от SELECT. Можете първо да използвате израза SELECT, за да извлечете стойностите на референтната колона и целевата колона.
SELECT e.City,A.City, e.PostCode,A.PostCode FROM Employee e INNER JOIN [Address] a ON e.EmpID = A.EmpID
След това ще извършите леки промени във вашата заявка и тя ще подготви оператор UPDATE, както е показано по-долу.
- Заменете избраната ключова дума с актуализация.
- Посочете името на таблицата или псевдонима, който трябва да бъде актуализиран.
- Използвайте зададена ключова дума и символ за равенство (=) между референтните и целевите колони.
UPDATE e set e.City=A.City, e.PostCode=A.PostCode FROM Employee e INNER JOIN [Address] a ON e.EmpID = A.EmpID
След това изпълнете оператора UPDATE и проверете дали стойностите на изходната и целевата колона са еднакви.
Метод 2:UPDATE от SELECT:оператор MERGE
Инструкцията MERGE е полезна за манипулиране на данни в целевата таблица въз основа на данните от изходната таблица както за съвпадащи, така и за несъпоставени редове. Това е алтернативен метод за извършване на UPDATE от функцията на оператора SELECT.
В примерния оператор MERGE по-долу се изпълняват следните задачи:
- Използвайте оператор MERGE за актуализиране на данни в таблицата [Служител].
- След това препраща към друга таблица, когато се приложи клаузата USING.
- След това WHEN MATCHED указва обединението JOIN (вътрешно свързване) между изходната и целевата таблица.
- След това актуализира [PostCode] и [City] от таблицата [Address] в таблицата [Employee], като използва израза THEN UPDATE, последвано от съпоставяния на изходна и целева колона.
- Изразът MERGE винаги завършва с точка и запетая (;).
MERGE Employee AS e USING(SELECT * FROM [Address]) AS A ON A.EmpID=e.EmpID WHEN MATCHED THEN UPDATE SET e.PostCode=A.PostCode , e.City = A.City;
Метод 3:АКТУАЛИЗИРАНЕ от SELECT:Метод на подзаявка
Подзаявката дефинира вътрешна заявка, която може да се използва в израза SELECT, INSERT, UPDATE и DELETE. Това е лесен метод за актуализиране на съществуващите таблици от други таблици.
UPDATE Employee SET Employee.City=(SELECT [Address].city FROM [Address] WHERE [Address].EmpID = Employee.EmpId)
- Горената заявка използва израз SELECT в клаузата SET на израза UPDATE.
- Ако подзаявката намери съвпадащ ред, заявката за актуализиране актуализира записите за конкретния служител.
- Ако подзаявката върне NULL (няма съвпадащ ред), тя актуализира NULL за съответната колона.
- Ако подзаявката върне повече от един съвпадащ ред, операторът UPDATE повдига грешка – „Подзаявката на SQL Server върна повече от 1 стойност. Това не е разрешено, когато подзаявката използва оператори за сравнение (=, !=, <, <=,>,>=).”
Ограничения на подзаявките
- Подзаявката с оператор за сравнение може да включва само едно име на колона, освен ако се използва за оператора IN или EXISTS. Следователно, ако изискваме актуализиране на множество колони с данни, се нуждаем от отделни SQL изрази.
- Не можете да използвате ntext , текст и изображение типове данни в подзаявката.
- Подзаявката не може да включва GROUP BY и клаузата HAVING, ако подзаявката съдържа немодифициран оператор за сравнение. Немодифицираният оператор за сравнение не може да използва ключовата дума ANY или ALL.
Сравнение на производителността между различни изрази UPDATE от SELECT
В този раздел ще направим сравнение на производителността между различни методи UPDATE от SELECT. За да направим това, ще започнем с изпълнение на SQL заявките заедно, като активираме действителния план за изпълнение (Ctrl + M) в SQL Server Management Studio и ще ги разделим с помощта на оператора Go.
В плановете за изпълнение получавам следните данни за моята демонстрация:
- Методът на присъединяване има 41% цена на заявката (в сравнение с цялата партида)
- Изявлението MERGE има 34% цена на заявката (в сравнение с цялата партида)
- Методът на подзаявката има 24% цена на заявката (в сравнение с цялата партида)
Методът JOIN използва 40% цена за отделно сортиране и 35% цена за актуализиране на клъстерен индекс.
Обединението за сливане използва вътрешно свързване за съпоставяне на редове с данни между изходните и целевите данни. Той също така има максимална относителна цена за оператора за сортиране.
Подзаявката е най-бързият метод за актуализиране на данните в колоните. Той използва актуализацията на клъстерирания индекс и сканирането на клъстериран индекс, както е подчертано.
За повече подробности можете да се обърнете към предишните ми статии: План за изпълнение на SQL Server — какво е това и как помага при проблеми с производителността? и Как да четете и анализирате планове за изпълнение на SQL Server.
Резюме
Можете да използвате всеки метод, посочен в тази статия, за изпълнение на UPDATE от оператори SELECT. Подзаявката работи ефективно, но има свои собствени ограничения, както беше подчертано по-рано. Цялостната производителност на вашата база данни зависи от данните в таблицата, броя на актуализациите, връзките на таблиците, индексите и статистическите данни.