Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Platí pro:SQL Server
Azure SQL Database
Spravovaná instance
Azure SQLAzure Synapse Analytics
PdW (Analytics Platform System)
Sklad v Microsoft Fabric
Databáze SQL v Microsoft Fabric
Změní existující data v tabulce nebo zobrazení v SQL Serveru. Příklady najdete v tématu Příklady.
Syntax
-- Syntax for SQL Server and Azure SQL Database
[ WITH <common_table_expression> [...n] ]
UPDATE
[ TOP ( expression ) [ PERCENT ] ]
{ { table_alias | <object> | rowset_function_limited
[ WITH ( <Table_Hint_Limited> [ ...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 ]
[ <OUTPUT Clause> ]
[ FROM{ <table_source> } [ ,...n ] ]
[ WHERE { <search_condition>
| { [ CURRENT OF
{ { [ GLOBAL ] cursor_name }
| cursor_variable_name
}
]
}
}
]
[ OPTION ( <query_hint> [ ,...n ] ) ]
[ ; ]
<object> ::=
{
[ server_name . database_name . schema_name .
| database_name .[ schema_name ] .
| schema_name .
]
table_or_view_name}
-- Syntax for Azure Synapse Analytics and Microsoft Fabric
[ WITH <common_table_expression> [ ,...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 {<join_table_source>}[ ,...n ]
ON <join_condition>
[ WHERE <search_condition> ]
[ OPTION ( LABEL = label_name ) ]
[;]
<join_table_source> ::=
{
[ database_name . [ schema_name ] . | schema_name . ] table_or_view_name [ AS ] table_or_view_alias
[ <tablesample_clause>]
| 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 <search_condition> ]
[ OPTION ( LABEL = label_name ) ]
[;]
Arguments
S <common_table_expression>
Specifikuje dočasně pojmenovanou sadu výsledků nebo pohled, známý také jako společný tabulkový výraz (CTE), definovaný v rámci UPDATE tohoto tvrzení. Výsledná sada CTE je odvozena z jednoduchého dotazu a je odkazována příkazem UPDATE .
Běžné tabulkové výrazy lze také použít s příkazy SELECT, INSERT, DELETE, a CREATE VIEW . Další informace najdete v tématu WITH common_table_expression (Transact-SQL).
TOP ( výraz) [ PERCENT ]
Určuje počet nebo procento aktualizovaných řádků.
výraz může být číslo nebo procento řádků.
Řádky uvedené v TOP výrazu používají , INSERTUPDATE, nebo DELETE nejsou uspořádány v žádném pořadí.
Závorky omezující výraz v TOP jsou vyžadovány v INSERT, UPDATE, a DELETE výrocích. Další informace naleznete v tématu TOP (Transact-SQL).
table_alias
Alias uvedený v klauzuli UPDATE reprezentující tabulku nebo pohled, ze kterého mají být řádky aktualizovány.
server_name
Je název serveru (pomocí názvu propojeného serveru nebo funkce OPENDATASOURCE jako název serveru), na kterém se nachází tabulka nebo zobrazení. Pokud je zadán server_name, database_name a schema_name jsou povinné.
database_name
Je název databáze.
schema_name
Je název schématu, do kterého patří tabulka nebo zobrazení.
table_or_view_name
Je název tabulky nebo zobrazení, ze kterého se mají řádky aktualizovat. Zobrazení, na které odkazuje table_or_view_name , musí být aktualizovatelné a odkazovat na přesně jednu základní tabulku v klauzuli FROM zobrazení. Pro více informací o aktualizovatelných zobrazeních viz CREATE VIEW (Transact-SQL).
rowset_function_limited
Je funkce OPENQUERY nebo OPENROWSET , která podléhá možnostem zprostředkovatele.
S (<Table_Hint_Limited>)
Určuje jeden nebo více tipů pro tabulku, které jsou povolené pro cílovou tabulku. Klíčové slovo WITH a závorky jsou povinné. NOLOCK, READUNCOMMITTED, NOEXPAND a několik dalších není povoleno. Informace o nápovědě k tabulce naleznete v tématu Nápověda k tabulce (Transact-SQL).
@
table_variable
Určuje proměnnou tabulky jako zdroj tabulky.
SET
Určuje seznam názvů sloupců nebo proměnných, které se mají aktualizovat.
column_name
Je sloupec obsahující data, která se mají změnit.
column_name musí existovat v table_or view_name. Sloupce identity se nedají aktualizovat.
expression
Je proměnná, literální hodnota, výraz nebo příkaz dílčího výběru (uzavřený se závorky), který vrací jednu hodnotu. Hodnota vrácená výrazem nahradí existující hodnotu v column_name nebo @proměnné.
Note
Při odkazování na datové typy znaků Unicode nchar, nvarchar a ntext by měla být předpona výrazu velkým písmenem N. Pokud není zadán znak N, SQL Server převede řetězec na znakovou stránku, která odpovídá výchozí kolaci databáze nebo sloupce. V této znakové stránce se ztratí žádné znaky, které nebyly nalezeny.
DEFAULT
Určuje, že výchozí hodnota definovaná pro sloupec má nahradit existující hodnotu ve sloupci. Můžete ho také použít ke změně sloupce na HODNOTU NULL, pokud sloupec nemá výchozí hodnotu a je definován tak, aby umožňoval hodnoty null.
{ +=-= | *=%= | | | | /=&= | ^= | |= }
Operátor složeného přiřazení:
+= Přidat a přiřadit
-= Odečíst a přiřadit
*= Násobení a přiřazení
/= Dělit a přiřazovat
%= Modulo a přiřazení
&= Bitwise AND a assign
^= Bitwise XOR a přiřazení
|= Bitwise OR a assign
udt_column_name
Je uživatelem definovaný sloupec typu.
property_name | field_name
Je veřejná vlastnost nebo veřejný datový člen uživatelem definovaného typu.
method_name(argument [ ;... n] )
Je nestatická metoda veřejného mutátoru udt_column_name , která přebírá jeden nebo více argumentů.
. WRITE (výraz,@Posun,@délka)
Určuje, že se má upravit oddíl hodnoty column_name .
výraz nahrazuje jednotky @Délka počínaje znakem @Posuncolumn_name. Pomocí této klauzule je možné zadat pouze sloupce varchar(max), nvarchar(max) nebo varbinary(max ).
column_name nemůže být NULL a nejde kvalifikovat s názvem tabulky nebo aliasem tabulky.
výraz je hodnota, která se zkopíruje do column_name. výraz musí být vyhodnocen jako nebo musí být implicitně přetypován na typ column_name . Pokud je výraz nastaven na HODNOTU NULL, je @Délka ignorována a hodnota v column_name je zkrácena na zadaném @Posunu.
@ Posun je výchozí bod v hodnotě uložené v column_name , při které je výraz zapsán. @ Posun je pozice řadového bajtu založená na nule, je velká a nemůže být záporné číslo. Pokud je hodnota @Posun NULL, operace aktualizace připojí výraz na konec existující hodnoty column_name a @Délka bude ignorována. Pokud je hodnota @Posun větší než délka bajtu column_name , databázový stroj vrátí chybu. Pokud @Posun plus @Délka překračuje konec podkladové hodnoty ve sloupci, dojde k odstranění až do posledního znaku hodnoty.
@ Délka je délka oddílu ve sloupci počínaje znakem @Posun, který je nahrazen výrazem. @ Délka je velká a nemůže být záporné číslo. Pokud je @Délka NULL, operace aktualizace odebere všechna data z @Posun na konec column_name hodnoty.
Další informace naleznete v tématu Aktualizace datových typů velkých hodnot.
@
proměnná
Je deklarovaná proměnná nastavená na hodnotu vrácenou výrazem.
SET @ proměnná = sloupec = Výraz nastaví proměnnou na stejnou hodnotu jako sloupec. To se liší od SET@proměnné = ve sloupcích = ,která nastavuje proměnnou na hodnotu sloupce před aktualizací.
<OUTPUT_Clause>
Vrací aktualizovaná data nebo výrazy na základě nich jako součást operace UPDATE . Klauzule OUTPUT není podporována v žádných příkazech DML, které cílí na vzdálené tabulky nebo zobrazení. Další informace o argumentech a chování této klauzule naleznete v tématu OUTPUT – klauzule (Transact-SQL).
OD <table_source>
Určuje, že se k zadání kritérií pro operaci aktualizace používá tabulka, zobrazení nebo odvozený zdroj tabulky. Další informace najdete v tématu FROM (Transact-SQL).
Pokud je objekt, který se aktualizuje, stejný jako objekt v klauzuli FROM a existuje pouze jeden odkaz na objekt v klauzuli FROM, může nebo nemusí být zadán alias objektu. Pokud se objekt, který se aktualizuje, zobrazí v klauzuli FROM vícekrát, jeden a pouze jeden, nesmí odkaz na objekt zadat alias tabulky. Všechny ostatní odkazy na objekt v klauzuli FROM musí obsahovat alias objektu.
Pohled s triggerem INSTEAD OF UPDATE nemůže být cílem a UPDATE s klauzulí FROM.
Note
Jakékoli volání OPENDATASOURCE, OPENQUERY nebo OPENROWSET v klauzuli FROM se vyhodnocuje samostatně a nezávisle na každém volání těchto funkcí používaných jako cíl aktualizace, i když jsou do těchto dvou volání zadány stejné argumenty. Konkrétně platí, že podmínky filtrování nebo spojení použité na výsledek jednoho z těchto volání nemají žádný vliv na výsledky druhého volání.
WHERE
Určuje podmínky, které omezují aktualizované řádky. Existují dvě formy aktualizace založené na tom, který formulář klauzule WHERE se používá:
Prohledané aktualizace určují podmínku hledání, která opravní řádky k odstranění.
Poziční aktualizace používají klauzuli CURRENT OF k určení kurzoru. Operace aktualizace probíhá na aktuální pozici kurzoru.
<search_condition>
Určuje podmínku, která se má splnit pro řádky, které se mají aktualizovat. Podmínkou může být také podmínka, na které je založeno spojení. Počet predikátů, které lze zahrnout do podmínky hledání, není nijak omezený. Další informace o predikátech a podmínkách hledání najdete v tématu Podmínka hledání (Transact-SQL).
SOUČASNOST
Určuje, že aktualizace se provádí na aktuální pozici zadaného kurzoru.
Poziční aktualizace pomocí klauzule WHERE CURRENT OF aktualizuje jeden řádek na aktuální pozici kurzoru. To může být přesnější než hledané aktualizace, která používá klauzuli WHERE <search_condition> kvalifikovat řádky, které se mají aktualizovat. Hledané aktualizace upraví více řádků, pokud podmínka hledání jednoznačně neidentifikuje jeden řádek.
GLOBAL
Určuje, že cursor_name odkazuje na globální kurzor.
cursor_name
Je název otevřeného kurzoru, ze kterého se má načíst. Pokud existuje globální i místní kurzor s názvem cursor_name existuje, odkazuje tento argument na globální kurzor, pokud je zadána funkce GLOBAL; v opačném případě odkazuje na místní kurzor. Kurzor musí povolit aktualizace.
cursor_variable_name
Je název proměnné kurzoru.
cursor_variable_name musí odkazovat na kurzor, který umožňuje aktualizace.
OPTION (<query_hint> [ ,... n ] )
Určuje, že se nápovědy optimalizátoru používají k přizpůsobení způsobu, jakým databázový stroj zpracovává příkaz. Další informace najdete v tématu Nápovědy k dotazům (Transact-SQL).
Osvědčené postupy
@@ROWCOUNT Funkce slouží k vrácení počtu vložených řádků do klientské aplikace. Pro více informací viz @@ROWCOUNT (Transact-SQL).
Názvy proměnných lze použít ve UPDATE výrocích k zobrazení starých a nových hodnot, které jsou ovlivněny, ale měly by být použity pouze tehdy, když příkaz ovlivňuje UPDATE jeden záznam. Pokud příkaz ovlivňuje UPDATE více záznamů, pro vrácení starých a nových hodnot pro každý záznam použijte klauzuli OUTPUT.
Při zadávání klauzule FROM při zadávání kritérií pro operaci aktualizace buďte opatrní. Výsledky příkazu UPDATE nejsou definovány, pokud příkaz obsahuje klauzuli FROM, která není specifikována tak, že pro každý sloupec, který se aktualizuje, je k dispozici pouze jedna hodnota, tedy pokud příkaz UPDATE není deterministický. Například ve UPDATE výroku v následujícím skriptu splňují oba řádky v Table1 podmínky klauzule FROM ve UPDATE výroku; ale není definováno, který řádek z Table1 se použije k aktualizaci řádku v Table2.
USE AdventureWorks2022;
GO
IF OBJECT_ID ('dbo.Table1', 'U') isn't NULL
DROP TABLE dbo.Table1;
GO
IF OBJECT_ID ('dbo.Table2', 'U') isn't 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;
Stejný problém může nastat při FROM kombinaci klauzulí a WHERE CURRENT OF klauzulí. V následujícím příkladu splňují oba řádky Table2FROM kvalifikace klauzule v UPDATE příkazu. Není definován, ze Table2 kterého řádku má být použit k aktualizaci řádku v Table1.
USE AdventureWorks2022;
GO
IF OBJECT_ID ('dbo.Table1', 'U') isn't NULL
DROP TABLE dbo.Table1;
GO
IF OBJECT_ID ('dbo.Table2', 'U') isn't 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
Podpora kompatibility
Podpora použití nápověd READUNCOMMITTED a NOLOCK v klauzuli FROM, které se vztahují na cílovou tabulku příkazu UPDATE ORDELETE, bude v budoucí verzi SQL Server odstraněna. Nepoužívejte tyto rady v tomto kontextu v nové vývojové práci a naplánujte úpravu aplikací, které je aktuálně používají.
Datové typy
Všechny sloupce typu char a nchar jsou správně vycpané na definovanou délku.
Pokud ANSI_PADDING je nastavení na VYPNUTO, všechny koncové mezery jsou odstraněny z dat vložených do sloupců varchar a nvarchar , kromě řetězců obsahujících pouze mezery. Tyto řetězce jsou zkráceny na prázdný řetězec. Pokud ANSI_PADDING je nastavení na ON, vkládají se zadní mezery. Ovladač Microsoft SQL Server ODBC a poskytovatel OLE DB pro SQL Server se automaticky nastaví ANSI_PADDING ON pro každé připojení. To lze nakonfigurovat ve zdrojích dat ODBC nebo nastavením atributů připojení nebo vlastností. Další informace najdete v tématu SET ANSI_PADDING (Transact-SQL).
Aktualizace sloupců textu, ntextu a obrázků
Úprava textového,ntextového nebo obrázkového sloupce s inicializuje UPDATE sloupec, přiřadí mu platný textový ukazatel a přidělí alespoň jednu datovou stránku, pokud se sloupec neaktualizuje pomocí NULL.
Pro nahrazení nebo úpravu velkých bloků textu, ntextu nebo obrazových dat použijte místo příkazu UPDATEWRITETEXT nebo UPDATETEXT.
Pokud UPDATE může příkaz změnit více než jeden řádek při aktualizaci jak klíče shlukování, tak jednoho nebo více textových, ntextových nebo obrázkových sloupců, částečná aktualizace těchto sloupců se provádí jako úplná náhrada hodnot.
Important
Datové typy ntext, text a image budou odebrány v budoucí verzi Microsoft SQL Serveru. Vyhněte se používání těchto datových typů v nové vývojové práci a naplánujte úpravu aplikací, které je aktuálně používají. Místo toho použijte nvarchar(max), varchar(max)a varbinary(max).
Aktualizace datových typů velkých hodnot
Použijte .Klauzule WRITE (výraz,Posun,Délka@@) pro provedení částečné nebo úplné aktualizace datových typů varchar(max), nvarchar(max) a varbinary(max).
Například částečná aktualizace sloupce varchar(max) může odstranit nebo upravit pouze prvních 200 bajtů sloupce (200 znaků při použití znaků ASCII), zatímco úplná aktualizace by odstranila nebo upravila všechna data ve sloupci. . Aktualizace zápisu , které vkládají nebo připojují nová data, se protokolují minimálně, pokud je model obnovení databáze nastavený na hromadně protokolované nebo jednoduché. Při aktualizaci existujících hodnot se nepoužívá minimální protokolování. Další informace naleznete v tématu Transakční protokol (SQL Server).
Database Engine převede částečnou aktualizaci na plnou, když UPDATE příkaz způsobí jednu z těchto akcí:
- Změní klíčový sloupec rozděleného zobrazení nebo tabulky.
- Upraví více než jeden řádek a aktualizuje také klíč neunique clusterovaného indexu na nekonstantní hodnotu.
Nemůžete použít . Klauzule WRITE pro aktualizaci sloupce NULL nebo nastavení hodnoty column_name na HODNOTU NULL.
@ Posun a @Délka jsou zadány v bajtech pro datové typy varbinary a varchar a v bajtových párech pro datový typ nvarchar . Další informace o délkách datových typů řetězců najdete v tématech char a varchar (Transact-SQL)a nchar a nvarchar (Transact-SQL).
Pro zajištění nejlepšího výkonu doporučujeme vložit nebo aktualizovat data v blocích dat, které jsou násobky 8040 bajtů.
Pokud sloupec upravil . Na klauzuli WRITE se odkazuje v klauzuli OUTPUT, úplná hodnota sloupce, a to buď před odstraněním obrázku.column_name nebo po vložení obrázku.column_name se vrátí do zadaného sloupce v proměnné tabulky. Podívejte se na příklad R, který následuje.
Chcete-li dosáhnout stejné funkce . ZÁPIS s jiným znakem nebo binárními datovými typy, použijte FUNKCI STUFF (Transact-SQL).
Aktualizace sloupců typ definovaných uživatelem
Aktualizace hodnot ve sloupcích typu definovaných uživatelem se dá provést jedním z následujících způsobů:
Zadání hodnoty v systémovém datovém typu SQL Serveru, pokud uživatelem definovaný typ podporuje implicitní nebo explicitní převod z daného typu. Následující příklad ukazuje, jak aktualizovat hodnotu ve sloupci uživatelem definovaného typu
Pointexplicitním převodem z řetězce.UPDATE Cities SET Location = CONVERT(Point, '12.3:46.2') WHERE Name = 'Anchorage';Vyvolání metody označené jako mutátor uživatelem definovaného typu k provedení aktualizace. Následující příklad vyvolá mutator metoda typu
Points názvemSetXY. Tím se aktualizuje stav instance typu.UPDATE Cities SET Location.SetXY(23.5, 23.5) WHERE Name = 'Anchorage';Note
SQL Server vrátí chybu, pokud je vyvolána metoda mutatoru na Transact-SQL hodnotu null nebo pokud nová hodnota vytvořená metodou mutatoru má hodnotu null.
Úprava hodnoty registrované vlastnosti nebo veřejného datového člena uživatelem definovaného typu Výraz poskytující hodnotu musí být implicitně konvertibilní na typ vlastnosti. Následující příklad upraví hodnotu vlastnosti
Xuživatelem definovaného typuPoint.UPDATE Cities SET Location.X = 23.5 WHERE Name = 'Anchorage';Pro úpravu různých vlastností stejného uživatelsky definovaného sloupce typu, zadání více UPDATE příkazů nebo vyvolání mutátorové metody daného typu.
Aktualizace dat FILESTREAM
Příkaz můžete použít UPDATE k aktualizaci pole FILESTREAM na nulovou hodnotu, prázdnou hodnotu nebo relativně malé množství dat v textu. Velké množství dat se ale efektivněji streamuje do souboru pomocí rozhraní Win32. Při aktualizaci pole FILESTREAM upravíte podkladová data objektu BLOB v systému souborů. Pokud je pole FILESTREAM nastaveno na HODNOTU NULL, data objektu blob přidružená k poli se odstraní. Nemůžete použít . WRITE() k provádění částečných aktualizací dat FILESTREAM. Další informace naleznete v tématu FILESTREAM (SQL Server).
Zpracování chyb
Pokud aktualizace řádku porušuje omezení nebo pravidlo, porušuje nastavení NULL pro sloupec nebo nová hodnota je nekompatibilní datový typ, příkaz se zruší, vrátí se chyba a nebudou aktualizovány žádné záznamy.
Když UPDATE příkaz narazí na aritmetickou chybu (přetečení, dělení nulou nebo chyba domény) během vyhodnocování výrazu, aktualizace se neprovede. Zbytek dávky se nespustí a vrátí se chybová zpráva.
Pokud aktualizace sloupce nebo sloupců, které se účastní clusterovaného indexu, způsobí, že velikost clusterovaného indexu a řádku překročí 8 060 bajtů, aktualizace se nezdaří a vrátí se chybová zpráva.
Interoperability
UPDATE Příkazy jsou povoleny v těle uživatelsky definovaných funkcí pouze tehdy, pokud je tabulka, kterou upravujeme, tabulková proměnná.
Když INSTEAD OF je spouštěč definován na UPDATE akce proti tabulce, spouštěč běží místo příkazu UPDATE . Starší verze SQL Server podporovaly pouze spouštěče AFTER definované na a UPDATE další příkazy pro úpravu dat. Klauzule FROM nemůže být specifikována ve příkazu UPDATE , který přímo nebo nepřímo odkazuje na pohled s definovaným INSTEAD OF triggerem. Pro více informací o spouštěčích INSTEAD OF viz CREATE TRIGGER (Transact-SQL).
V současné době nelze klauzuli FROM specifikovat ve výpisu UPDATE o Warehouse v Microsoft Fabric. Podporována jsou výroku s jedním stolem UPDATE .
Limity a omezení
Klauzule FROM nemůže být specifikována ve příkazu UPDATE , který přímo nebo nepřímo odkazuje na pohled, na kterém je definován spouštěč INSTEAD OF . Pro více informací o INSTEAD OF spouštěčích viz CREATE TRIGGER (Transact-SQL).
Když je cílem věty UPDATE běžný tabulkový výraz (CTE), musí všechny odkazy na CTE ve výroku odpovídat. Pokud je například CTE přiřazen alias v klauzuli FROM, musí být alias použit pro všechny ostatní odkazy na CTE. Jednoznačné odkazy CTE jsou vyžadovány, protože CTE nemá ID objektu, které SQL Server používá k rozpoznávání implicitního vztahu mezi objektem a jeho aliasem. Bez této relace může plán dotazu vést k neočekávanému chování spojení a nechtěným výsledkům dotazu. Následující příklady ukazují správné a nesprávné metody určení CTE, pokud je CTE cílovým objektem operace aktualizace.
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
Tady je soubor výsledků.
ID Value
------ -----
1 100
2 200
(2 row(s) affected)
UPDATE tvrzení s odkazy na CTE, které jsou nesprávně spárovány.
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 isn't 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
Tady je soubor výsledků.
ID Value
------ -----
1 100
2 100
(2 row(s) affected)
Chování při uzamčení
Příkaz UPDATE získá výhradníX () zámek na všech řádcích, které upraví, a drží tyto zámky až do dokončení transace. V závislosti na plánu dotazu pro UPDATE příkaz, počtu řádků upravovaných a úrovni izolace transakce mohou být zámky získány na úrovni stránky nebo tabulky, nikoli na úrovni řádku. Abyste těmto zámkům na vyšší úrovni předešli, zvažte rozdělení aktualizačních příkazů, které ovlivňují tisíce řádků nebo více do dávek, a zajistěte, aby indexy podporovaly všechny podmínky spojení a filtru. Další podrobnosti o zamykání mechaniky v SQL Serveru najdete v článku o uzamčení databázového stroje .
Pokud je povolené optimalizované uzamčení, některé aspekty chování uzamčení UPDATE se změní. Například exkluzivní zámky (X) se neudržují, dokud se transakce nedokončí. Další informace naleznete v tématu Optimalizované uzamčení.
Chování logování
Příkaz UPDATE je zaznamenán; nicméně částečné aktualizace datových typů s velkou hodnotou pomocí . Klauzule WRITE jsou minimálně zaznamenávány. Další informace najdete v části "Aktualizace datových typů velkých hodnot" v předchozí části Datové typy.
Zabezpečení
Permissions
UPDATE oprávnění jsou vyžadována v cílové tabulce.
SELECT oprávnění jsou také vyžadována pro tabulku, která se aktualizuje, pokud UPDATE příkaz obsahuje klauzuli WHERE nebo pokud výraz v klauzuli SET používá sloupec v tabulce.
UPDATE Oprávnění jsou výchozí pro členy sysadmin pevné serverové role, db_owner a pevné databázové role a db_datawriter vlastníka tabulky. Členové , sysadmina db_ownerrole a db_securityadmin vlastník tabulky mohou přenášet oprávnění jiným uživatelům.
Examples
| Category | Doporučené prvky syntaxe |
|---|---|
| Základní syntaxe | UPDATE |
| Omezení aktualizovaných řádků | WHERE * TOP * WITH společný výraz tabulky * WHERE CURRENT OF |
| Nastavení hodnot sloupců | vypočítané hodnoty * složené operátory * výchozí hodnoty * poddotazy |
| Určení cílových objektů kromě standardních tabulek | zobrazení * proměnné tabulky * aliasy tabulek |
| Aktualizace dat na základě dat z jiných tabulek | FROM |
| Aktualizace řádků ve vzdálené tabulce | odkazovaný server * OPENQUERY * OPENDATASOURCE |
| Aktualizace velkých datových typů objektů | . NAPSAT * OPENROWSET |
| Aktualizace uživatelem definovaných typů | Uživatelem definované typy |
| Přepsání výchozího chování optimalizátoru dotazů pomocí tipů | rady k tabulce * nápovědy k dotazům |
| Zachycení výsledků UPDATE prohlášení | Klauzule OUTPUT |
| Použití UPDATE v jiných tvrzeních | Uložené procedury * TRY... CHYTIT |
Základní syntaxe
Příklady v této sekci ukazují základní funkčnost UPDATE výroku pomocí minimální požadované syntaxe.
A. Použití jednoduchého UPDATE tvrzení
Následující příklad aktualizuje jeden sloupec pro všechny řádky v Person.Address tabulce.
USE AdventureWorks2022;
GO
UPDATE Person.Address
SET ModifiedDate = GETDATE();
B. Aktualizace více sloupců
Následující příklad aktualizuje hodnoty v objektu Bonus, CommissionPcta SalesQuota sloupce pro všechny řádky v SalesPerson tabulce.
USE AdventureWorks2022;
GO
UPDATE Sales.SalesPerson
SET Bonus = 6000, CommissionPct = .10, SalesQuota = NULL;
GO
Omezení aktualizovaných řádků
Příklady v této sekci ukazují způsoby, jak omezit počet řádků ovlivněných tvrzením UPDATE .
C. Použití klauzule WHERE
Následující příklad používá klauzuli WHERE k určení, které řádky se mají aktualizovat. Příkaz aktualizuje hodnotu ve Color sloupci Production.Product tabulky pro všechny řádky, které mají ve Color sloupci existující hodnotu Red a mají hodnotu ve Name sloupci, která začíná na Road-250.
USE AdventureWorks2022;
GO
UPDATE Production.Product
SET Color = N'Metallic Red'
WHERE Name LIKE N'Road-250%' AND Color = N'Red';
GO
D. Použití klauzule TOP
Následující příklady používají klauzuli TOP k omezení počtu řádků, které jsou ve příkazu UPDATE upraveny. Když je použita klauzule TOP (n) s UPDATE, aktualizace se provádí na náhodném výběru 'n' počtu řádků. Následující příklad aktualizuje VacationHours sloupec o 25 procent pro 10 náhodných řádků v Employee tabulce.
USE AdventureWorks2022;
GO
UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25 ;
GO
Pokud je nutné použít TOP k použití aktualizací ve smysluplné chronologii, musíte použít TOP společně s ORDER BY v dílčím příkazu výběru. Následující příklad aktualizuje pracovní dobu 10 zaměstnanců s nejstarším datem přijetí.
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
E. Použití klauzule WITH common_table_expression
Následující příklad aktualizuje PerAssemblyQty hodnotu pro všechny části a komponenty, které se používají přímo nebo nepřímo k vytvoření ProductAssemblyID 800. Výraz společné tabulky vrátí hierarchický seznam částí, které se používají přímo k sestavení a částí, které se používají k sestavení ProductAssemblyID 800 těchto součástí atd. Upraví se jenom řádky vrácené běžným výrazem tabulky.
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;
F. Použití klauzule WHERE CURRENT OF
Následující příklad používá klauzuli WHERE CURRENT OF k aktualizaci pouze řádku, na kterém je kurzor umístěn. Když je kurzor založen na joinu, mění se pouze to, co je ve příkazu UPDATE specifikovánotable_name. Ostatní tabulky, které se účastní kurzoru, nejsou ovlivněny.
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
Nastavení hodnot sloupců
Příklady v této sekci ukazují aktualizaci sloupců pomocí vypočítaných hodnot, poddotazů a DEFAULT hodnot.
G. Určení vypočítané hodnoty
Následující příklady používají vypočítané hodnoty ve výrocích UPDATE . Příklad zdvojnásobí hodnotu ve ListPrice sloupci pro všechny řádky v Product tabulce.
USE AdventureWorks2022;
GO
UPDATE Production.Product
SET ListPrice = ListPrice * 2;
GO
H. Určení složeného operátoru
Následující příklad používá proměnnou @NewPrice k zvýšení ceny všech červených kol tím, že vezme aktuální cenu a přidá k ní 10.
USE AdventureWorks2022;
GO
DECLARE @NewPrice INT = 10;
UPDATE Production.Product
SET ListPrice += @NewPrice
WHERE Color = N'Red';
GO
Následující příklad používá složený operátor += k připojení dat ' - tool malfunction' k existující hodnotě ve sloupci Name pro řádky, které mají ScrapReasonID mezi 10 a 12.
USE AdventureWorks2022;
GO
UPDATE Production.ScrapReason
SET Name += ' - tool malfunction'
WHERE ScrapReasonID BETWEEN 10 and 12;
I. Specifikace poddotazu ve klauzuli SET
Následující příklad používá poddotaz v klauzuli SET k určení hodnoty, která se použije k aktualizaci sloupce. Poddotaz musí vracet pouze skalární hodnotu (to znamená jednu hodnotu na řádek). Příklad upraví SalesYTD sloupec v SalesPerson tabulce tak, aby odrážel nejnovější prodeje zaznamenané v SalesOrderHeader tabulce. Poddotaz agreguje prodeje pro každého prodejce v UPDATE příkazu.
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
J. Aktualizace řádků pomocí DEFAULT hodnot
Následující příklad nastaví CostRate sloupec na výchozí hodnotu (0,00) pro všechny řádky, které mají CostRate hodnotu větší než 20.00.
USE AdventureWorks2022;
GO
UPDATE Production.Location
SET CostRate = DEFAULT
WHERE CostRate > 20.00;
Určení jiných cílových objektů než standardních tabulek
Příklady v této části ukazují, jak aktualizovat řádky zadáním zobrazení, aliasu tabulky nebo proměnné tabulky.
K. Zadání zobrazení jako cílového objektu
Následující příklad aktualizuje řádky v tabulce zadáním zobrazení jako cílového objektu. Definice zobrazení odkazuje na více tabulek, avšak tvrzení je úspěšné, UPDATE protože odkazuje pouze na sloupce z jedné z podkladových tabulek. Příkaz UPDATE by selhal, pokud by byly specifikovány sloupce z obou tabulek. Další informace naleznete v tématu Úprava dat prostřednictvím zobrazení.
USE AdventureWorks2022;
GO
UPDATE Person.vStateProvinceCountryRegion
SET CountryRegionName = 'United States of America'
WHERE CountryRegionName = 'United States';
L. Zadání aliasu tabulky jako cílového objektu
Následující příklad aktualizuje řádky v tabulce Production.ScrapReason. Tabulkový alias přiřazený v ScrapReason klauzuli FROM je určen jako cílový objekt v klauzuli 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;
M. Určení proměnné tabulky jako cílového objektu
Následující příklad aktualizuje řádky v proměnné tabulky.
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
Aktualizace dat na základě dat z jiných tabulek
Příklady v této části ukazují metody aktualizace řádků z jedné tabulky na základě informací v jiné tabulce.
N. Použití UPDATE výroku s informacemi z jiné tabulky
Následující příklad upraví SalesYTD sloupec v SalesPerson tabulce tak, aby odrážel nejnovější prodeje zaznamenané v SalesOrderHeader tabulce.
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
Předchozí příklad předpokládá, že pro konkrétního prodejce se zaznamená pouze jeden prodej a že aktualizace jsou aktuální. Pokud je možné na stejný den zaznamenat více než jeden prodej pro konkrétního prodejce, nebude zobrazený příklad fungovat správně. Příklad se spustí bez chyby, ale každá SalesYTD hodnota se aktualizuje pouze o jeden prodej bez ohledu na to, kolik prodejů skutečně nastalo v daný den. Je to proto, že jeden UPDATE příkaz nikdy neaktualizuje stejný řádek dvakrát.
V situaci, kdy může dojít ke stejnému dni více než jeden prodej pro konkrétního prodejce, musí být všechny prodeje pro každou prodejní osobu agregovány společně v rámci příkazu, jak je znázorněno v následujícím příkladu 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
Aktualizace řádků ve vzdálené tabulce
Příklady v této části ukazují, jak aktualizovat řádky ve vzdálené cílové tabulce pomocí propojeného serveru nebo funkce sady řádků pro odkazování na vzdálenou tabulku.
O. Aktualizace dat ve vzdálené tabulce pomocí propojeného serveru
Následující příklad aktualizuje tabulku na vzdáleném serveru. Příklad začíná vytvořením propojení se vzdáleným zdrojem dat pomocí sp_addlinkedserver. Název MyLinkedServerpropojeného serveru je poté zadán jako součást názvu objektu ve formuláři server.catalog.schema.object. Všimněte si, že je nutné zadat platný název serveru pro @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'<server name>',
@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;
P. Aktualizace dat ve vzdálené tabulce pomocí funkce OPENQUERY
Následující příklad aktualizuje řádek ve vzdálené tabulce zadáním funkce OPENQUERY rowset. V tomto příkladu se používá název propojeného serveru vytvořený v předchozím příkladu.
UPDATE OPENQUERY (MyLinkedServer, 'SELECT GroupName FROM HumanResources.Department WHERE DepartmentID = 4')
SET GroupName = 'Sales and Marketing';
Q. Aktualizace dat ve vzdálené tabulce pomocí funkce OPENDATASOURCE
Následující příklad aktualizuje řádek ve vzdálené tabulce zadáním funkce OPENDATASOURCE rowset. Zadejte platný název serveru pro zdroj dat pomocí formátu server_name nebo server_name\instance_name. Možná budete muset nakonfigurovat instanci SQL Serveru pro distribuované dotazy ad hoc. Další informace najdete v tématu ad hoc distribuované dotazy Možnost konfigurace serveru.
UPDATE OPENDATASOURCE('SQLNCLI', 'Data Source=<server name>;Integrated Security=SSPI').AdventureWorks2022.HumanResources.Department
SET GroupName = 'Sales and Marketing' WHERE DepartmentID = 4;
Aktualizace datových typů Velké objekty
Příklady v této části ukazují metody aktualizace hodnot ve sloupcích definovaných s velkými datovými typy objektů (LOB).
R. Použitím UPDATE s . WRITE pro úpravu dat ve sloupci nvarchar(max)
Následující příklad používá . Klauzule WRITE pro aktualizaci částečné hodnoty ve DocumentSummarysloupci nvarchar(max) v Production.Document tabulce. Slovo components se nahradí slovem features zadáním náhradního slova, počátečním umístěním (posunem) slova, které se má nahradit v existujících datech, a počtem znaků, které se mají nahradit (délka). Příklad také používá klauzuli OUTPUT k vrácení před a za obrázky DocumentSummary sloupce do @MyTableVar proměnné tabulky.
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
S. Použitím UPDATE s . WRITE pro přidání a odstranění dat ve sloupci nvarchar(max)
Následující příklady přidají a odeberou data ze sloupce nvarchar(max), který má aktuálně nastavenou hodnotu NULL. Protože . Klauzule WRITE se nedá použít k úpravě sloupce NULL, sloupec se nejprve naplní dočasnými daty. Tato data se pak nahradí správnými daty pomocí funkce . Klauzule WRITE. Další příklady připojují data na konec hodnoty sloupce, odeberou (zkrácená) data ze sloupce a nakonec odeberou částečná data ze sloupce. Příkazy SELECT zobrazují datovou úpravu generovanou každým UPDATE příkazem.
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. Použití UPDATE pomocí OPENROWSET pro úpravu varbinárního sloupce (max)
Následující příklad nahradí existující obrázek uložený ve sloupci varbinary(max) novým obrázkem. Funkce OPENROWSET se používá s možností BULK k načtení obrázku do sloupce. Tento příklad předpokládá, že v zadané cestě k souboru existuje pojmenovaný Tires.jpg soubor.
USE AdventureWorks2022;
GO
UPDATE Production.ProductPhoto
SET ThumbNailPhoto = (
SELECT *
FROM OPENROWSET(BULK 'c:Tires.jpg', SINGLE_BLOB) AS x )
WHERE ProductPhotoID = 1;
GO
U. Použití UPDATE pro úpravu dat FILESTREAM
Následující příklad používá UPDATE příkaz k úpravě dat v souboru souborového systému. Tuto metodu nedoporučujeme pro streamování velkých objemů dat do souboru. Použijte příslušná rozhraní Win32. Následující příklad nahradí veškerý text v záznamu souboru textem Xray 1. Další informace naleznete v tématu FILESTREAM (SQL Server).
UPDATE Archive.dbo.Records
SET [Chart] = CAST('Xray 1' as VARBINARY(max))
WHERE [SerialNumber] = 2;
Aktualizace uživatelem definovaných typů
Následující příklady upravují hodnoty ve sloupcích UDT (User-defined type) CLR. Demonstrují se tři metody. Další informace o uživatelem definovaných sloupcích naleznete v tématu CLR User-Defined Typy.
V. Použití systémového datového typu
UDT můžete aktualizovat zadáním hodnoty v systémovém datovém typu SQL Serveru, pokud uživatel definovaný typ podporuje implicitní nebo explicitní převod z daného typu. Následující příklad ukazuje, jak aktualizovat hodnotu ve sloupci uživatelem definovaného typu Pointexplicitním převodem z řetězce.
UPDATE dbo.Cities
SET Location = CONVERT(Point, '12.3:46.2')
WHERE Name = 'Anchorage';
W. Vyvolání metody
UDT můžete aktualizovat vyvoláním metody označené jako mutátoru uživatelem definovaného typu k provedení aktualizace. Následující příklad vyvolá mutator metoda typu Point s názvem SetXY. Tím se aktualizuje stav instance typu.
UPDATE dbo.Cities
SET Location.SetXY(23.5, 23.5)
WHERE Name = 'Anchorage';
X. Úprava hodnoty vlastnosti nebo datového členu
UDT můžete aktualizovat úpravou hodnoty registrované vlastnosti nebo veřejného datového člena uživatelem definovaného typu. Výraz poskytující hodnotu musí být implicitně konvertibilní na typ vlastnosti. Následující příklad upraví hodnotu vlastnosti X uživatelem definovaného typu Point.
UPDATE dbo.Cities
SET Location.X = 23.5
WHERE Name = 'Anchorage';
Přepsání výchozího chování optimalizátoru dotazů pomocí tipů
Příklady v této sekci ukazují, jak použít tabulkové a dotazové nápovědy k dočasnému přepsání výchozího chování optimalizátoru dotazu při zpracování příkazu UPDATE .
Caution
Vzhledem k tomu, že optimalizátor dotazů SQL Serveru obvykle vybírá nejlepší plán provádění dotazu, doporučujeme, aby se rady používaly pouze jako poslední možnost zkušenými vývojáři a správci databází.
Y. Zadání nápovědy k tabulce
Následující příklad určuje tabulkový tip TABLOCK. Tato nápověda specifikuje, že sdílený zámek je na stole Production.Product přijat a držen až do konce příkazu UPDATE .
USE AdventureWorks2022;
GO
UPDATE Production.Product
WITH (TABLOCK)
SET ListPrice = ListPrice * 1.10
WHERE ProductNumber LIKE 'BK-%';
GO
Z. Zadání nápovědy k dotazu
Následující příklad specifikuje dotazovací nápověduOPTIMIZE FOR (@variable) ve tvrzení.UPDATE Tento tip dává optimalizátoru dotazů pokyn, aby při kompilaci a optimalizaci dotazu použil konkrétní hodnotu pro místní proměnnou. Hodnota se používá pouze při optimalizaci dotazu, a ne během provádění dotazu.
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-%';
Zachycení výsledků UPDATE tvrzení
Příklady v této sekci ukazují, jak použít klauzuli OUTPUT k vrácení informací z každého řádku ovlivněného příkazem UPDATE , nebo na základě výrazů. Tyto výsledky je možné vrátit do aplikace pro zpracování pro použití, jako jsou potvrzovací zprávy, archivace a další požadavky na aplikaci.
AA. Použití UPDATE s klauzulí OUTPUT
Následující příklad aktualizuje sloupec VacationHours v Employee tabulce o 25 procent pro zaměstnance s méně než 10 VacationHours a také nastaví hodnotu ve sloupci ModifiedDate na aktuální datum. Klauzule OUTPUT vrátí hodnotu VacationHours , která existuje před použitím UPDATE příkazu ve deleted.VacationHours sloupci a aktualizované hodnoty ve inserted.VacationHours sloupci na proměnnou @MyTableVar tabulky.
Následují dva SELECT příkazy, které vrátí hodnoty v @MyTableVar tabulce a výsledky operace aktualizace.Employee Další příklady použití klauzule OUTPUT naleznete v tématu OUTPUT – klauzule (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
Použití UPDATE v jiných tvrzeních
Příklady v této části ukazují, jak použít UPDATE v jiných výrocích.
Krevní skupina. Použití UPDATE v uložené procedurě
Následující příklad používá UPDATE příkaz v uložené procedurě. Procedura přebírá jeden vstupní parametr @NewHoursa jeden výstupní parametr @RowCount. Hodnota @NewHours parametru se použije ve příkazu UPDATE k aktualizaci sloupce VacationHours v tabulce HumanResources.Employee. Výstupní @RowCount parametr slouží k vrácení počtu řádků ovlivněných místní proměnné. Výraz CASE se používá ve klauzuli SET k podmíněnému určení hodnoty nastavené pro VacationHours. Pokud je zaměstnanec placen každou hodinu (SalariedFlag = 0), VacationHours je nastaven na aktuální počet hodin plus hodnota zadaná v @NewHours; v opačném případě VacationHours je nastavena na hodnotu zadanou v @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;
Střídavý proud. Použití UPDATE ve SNAZE... CATCH Block
Následující příklad používá UPDATE příkaz v TRY... CATCH blok pro řešení chyb při vykonávání, které mohou nastat během aktualizace operace.
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
Příklady: Azure Synapse Analytics a Analytický platformový systém (PDW)
REKLAMA. Použití jednoduchého UPDATE tvrzení
Následující příklady ukazují, jak mohou být ovlivněny všechny řádky, pokud klauzule WHERE není použita k určení řádku (nebo řádků) k aktualizaci.
Tento příklad aktualizuje hodnoty ve EndDate sloupcích a CurrentFlag pro všechny řádky v DimEmployee tabulce.
-- Uses AdventureWorks
UPDATE DimEmployee
SET EndDate = '2010-12-31', CurrentFlag='False';
Ve výčtu můžete také použít vypočtené hodnoty UPDATE . Následující příklad zdvojnásobí hodnotu ve ListPrice sloupci pro všechny řádky v Product tabulce.
-- Uses AdventureWorks
UPDATE DimEmployee
SET BaseRate = BaseRate * 2;
Æ. Použití UPDATE tvrzení s klauzulí WHERE
Následující příklad používá klauzuli WHERE k určení, které řádky se mají aktualizovat.
-- Uses AdventureWorks
UPDATE DimEmployee
SET FirstName = 'Gail'
WHERE EmployeeKey = 500;
AF. Použití příkazu UPDATE s označením
Následující příklad ukazuje použití LABEL pro UPDATE toto tvrzení.
-- Uses AdventureWorks
UPDATE DimProduct
SET ProductSubcategoryKey = 2
WHERE ProductKey = 313
OPTION (LABEL = N'label1');
AG. Použití UPDATE výroku s informacemi z jiné tabulky
Tento příklad vytvoří tabulku pro ukládání celkového prodeje po roce. Aktualizuje celkové prodeje za rok 2004 spuštěním příkazu SELECT v tabulce 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;
ACH. ANSI se připojit pro aktualizace
Tento příklad ukazuje, jak aktualizovat data na základě výsledku spojení jiné tabulky.
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
Viz také
CREATE TABLE (Transact-SQL)
CREATE TRIGGER (Transact-SQL)
Kurzory (Transact-SQL)
DELETE (Transact-SQL)
INSERT (Transact-SQL)
Funkce textu a obrázku (Transact-SQL)
WITH common_table_expression (Transact-SQL)
FILESTREAM (SQL Server)
podpora kolace a kódování Unicode
Single-Byte a vícebajtové znakové sady