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>
Určuje dočasnou pojmenovanou sadu výsledků nebo zobrazení, označovanou také jako common table expression (CTE), definovanou v rámci oboru příkazu UPDATE. Sada výsledků CTE je odvozena z jednoduchého dotazu a odkazuje se na příkazEM UPDATE.
Běžné výrazy tabulky lze použít také 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 odkazované ve výrazu TOP použitém s příkazem INSERT, UPDATE nebo DELETE nejsou uspořádané v žádném pořadí.
V příkazech INSERT, UPDATE a DELETE jsou vyžadovány závorky oddělovače výrazů TOP. Další informace naleznete v tématu TOP (Transact-SQL).
table_alias
Alias zadaný v klauzuli UPDATE představující tabulku nebo zobrazení, ze kterého se mají řádky aktualizovat.
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í. Další informace o aktualizovatelných zobrazeních naleznete v tématu 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 = = nastaví proměnnou na stejnou hodnotu jako sloupec. Liší se od@proměnné = SET, výraz sloupce = , který nastaví proměnnou na hodnotu před aktualizací sloupce.
<OUTPUT_Clause>
Vrátí aktualizovaná data nebo výrazy založené na ní 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.
Zobrazení s triggerem MÍSTO AKTUALIZACE nemůže být cílem funkce 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. Další informace naleznete v tématu @@ROWCOUNT (Transact-SQL).
Názvy proměnných lze použít v příkazech UPDATE k zobrazení starých a nových hodnot, které jsou ovlivněny, ale to by se mělo použít pouze v případě, že příkaz UPDATE ovlivňuje jeden záznam. Pokud příkaz UPDATE ovlivňuje více záznamů, k 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í určena takovým způsobem, že je k dispozici pouze jedna hodnota pro každý výskyt sloupce, který je aktualizován, to znamená, že příkaz UPDATE není deterministický. Například v příkazu UPDATE v následujícím skriptu oba řádky splňují Table1 kvalifikace klauzule FROM v příkazu UPDATE, ale není definován, ze Table1 kterého řádku se používá k aktualizaci řádku v příkazu UPDATE. 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ědy READUNCOMMITTED a NOLOCK v klauzuli FROM, které platí pro cílovou tabulku příkazu UPDATE nebo DELETE, budou odebrány v budoucí verzi SQL Serveru. 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 je ANSI_PADDING nastavena na hodnotu VYPNUTO, odeberou se ze všech koncových mezer vložených do sloupců varchar a nvarchar s výjimkou řetězců, které obsahují pouze mezery. Tyto řetězce jsou zkráceny na prázdný řetězec. Pokud je ANSI_PADDING nastavená na ZAPNUTO, vloží se koncové mezery. Ovladač MICROSOFT SQL Server ODBC a zprostředkovatel OLE DB pro SQL Server 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 naleznete 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 pomocí funkce UPDATE inicializuje sloupec, přiřadí k němu platný textový ukazatel a přidělí alespoň jednu datovou stránku, pokud se sloupec neaktualizuje hodnotou NULL.
Chcete-li nahradit nebo upravit velké bloky textu, ntext nebo obrazová data, použijte místo příkazu UPDATE text WRITETEXT nebo UPDATETEXT .
Pokud by příkaz UPDATE mohl změnit více než jeden řádek při aktualizaci klíče clusteringu i jednoho nebo více sloupců textu, ntextu nebo obrázku , provede se částečná aktualizace těchto sloupců 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).
Databázový stroj převede částečnou aktualizaci na úplnou aktualizaci, když příkaz UPDATE 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';Chcete-li upravit různé vlastnosti stejného uživatelem definovaného sloupce typu, vydat více příkazů UPDATE nebo vyvolat mutator metodu typu.
Aktualizace dat FILESTREAM
Příkaz UPDATE můžete použít k aktualizaci pole FILESTREAM na hodnotu null, prázdnou hodnotu nebo relativně malé množství vložených dat. 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ž příkaz UPDATE během vyhodnocování výrazu narazí na aritmetickou chybu (přetečení, dělení nulou nebo chybou domény), aktualizace se neprovádí. 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
Příkazy UPDATE jsou povoleny v těle uživatelem definovaných funkcí pouze v případě, že upravená tabulka je proměnná tabulky.
Pokud je aktivační událost definována INSTEAD OF pro akce UPDATE v tabulce, aktivační událost je spuštěna místo příkazu UPDATE. Starší verze SQL Serveru podporují pouze triggery AFTER definované v aktualizaci a dalších příkazech pro úpravy dat. Klauzule FROM nelze zadat v příkazu UPDATE, který odkazuje přímo nebo nepřímo na zobrazení s triggerem definovaným INSTEAD OF na něm. Další informace o triggerech MÍSTO triggerů najdete v tématu CREATE TRIGGER (Transact-SQL).
V současné době nelze klauzuli FROM zadat v příkazu UPDATE ve službě Warehouse v Microsoft Fabric. Podporují se příkazy UPDATE s jednou tabulkou.
Limity a omezení
Klauzule FROM nemůže být zadána v příkazu UPDATE, který odkazuje přímo nebo nepřímo na zobrazení s triggerem definovaným INSTEAD OF v něm. Další informace o aktivačních událostech najdete v INSTEAD OF tématu CREATE TRIGGER (Transact-SQL).
Pokud je cílem příkazu UPDATE společný výraz tabulky (CTE), musí se všechny odkazy na CTE v příkazu shodovat. 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)
Příkaz UPDATE s odkazy CTE, které jsou nesprávně shodné.
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í zámek (X) na všech řádcích, které upravuje, a uchovává tyto zámky, dokud transakce nebude dokončena. V závislosti na plánu dotazu pro příkaz UPDATE, počet upravovaných řádků a úroveň 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 protokolován; částečné aktualizace datových typů s velkou hodnotou však pomocí . Klauzule WRITE se protokoluje minimálně. 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 vyžadována také pro tabulku, která se aktualizuje, pokud příkaz UPDATE obsahuje klauzuli WHERE nebo pokud výraz v klauzuli SET používá sloupec v tabulce.
Ve výchozím nastavení aktualizujte oprávnění pro členy sysadmin pevné role serveru, db_owner role a db_datawriter pevné databázové role a 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 |
| Zaznamenání výsledků příkazu UPDATE | Klauzule OUTPUT |
| Použití funkce UPDATE v jiných příkazech | Uložené procedury * TRY... CHYTIT |
Základní syntaxe
Příklady v této části ukazují základní funkce příkazu UPDATE pomocí minimální požadované syntaxe.
A. Použití jednoduchého příkazu UPDATE
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 části ukazují způsoby, jak můžete použít k omezení počtu řádků ovlivněných příkazem 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 upraveny v příkazu UPDATE. Při použití klauzule TOP (n) s aktualizací se operace aktualizace provede s náhodným výběrem "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. Pokud je kurzor založen na spojení, změní se pouze table_name zadaný v příkazu UPDATE. 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 části ukazují aktualizaci sloupců pomocí vypočítaných hodnot, poddotazů a výchozích hodnot.
G. Určení vypočítané hodnoty
Následující příklady používají vypočítané hodnoty v příkazu 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. Zadání poddotazu v klauzuli SET
Následující příklad používá poddotaz v klauzuli SET k určení hodnoty, která se používá 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í výchozích 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í však odkazuje na více tabulek, příkaz UPDATE je úspěšný, protože odkazuje na sloupce pouze z jedné z podkladových tabulek. Příkaz UPDATE selže, pokud byly zadá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. Alias tabulky přiřazený ScrapReason v 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í příkazu UPDATE 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. Důvodem je to, že jeden příkaz UPDATE nikdy dvakrát neaktualizuje stejný řádek.
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. Pomocí funkce UPDATE s . ZÁPIS 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. Pomocí funkce UPDATE s . ZÁPIS pro přidání a odebrá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í úpravy dat vygenerované jednotlivými příkazy 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. Úprava sloupce varbinary(max) pomocí funkce UPDATE s FUNKCÍ OPENROWSET
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í funkce UPDATE k úpravě dat FILESTREAM
Následující příklad používá příkaz UPDATE k úpravě dat v souboru systému souborů. 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 části ukazují, jak pomocí tabulek a tipů dotazů dočasně přepsat výchozí chování optimalizátoru dotazů 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. Tento tip určuje, že sdílený zámek je pořízen v tabulce Production.Product a ulož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 určuje nápověduOPTIMIZE FOR (@variable) dotazu v příkazu 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ů příkazu UPDATE
Příklady v této části ukazují, jak pomocí klauzule OUTPUT vracet informace z výrazů nebo výrazů založených na jednotlivých řádcích ovlivněných příkazem UPDATE. 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í funkce 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í funkce UPDATE v jiných příkazech
Příklady v této části ukazují, jak použít update v jiných příkazech.
Krevní skupina. Použití funkce UPDATE v uložené proceduře
Následující příklad používá příkaz UPDATE v uložené procedurě. Procedura přebírá jeden vstupní parametr @NewHoursa jeden výstupní parametr @RowCount. Hodnota @NewHours parametru se používá v 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á v 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í funkce UPDATE v try... Blok CATCH
Následující příklad používá příkaz UPDATE v try... Blok CATCH pro zpracování chyb spuštění, ke kterým může dojít během operace aktualizace.
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 příkazu UPDATE
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';
Počítané hodnoty můžete použít také v příkazu 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í příkazu UPDATE 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 popiskem
Následující příklad ukazuje použití LABEL pro příkaz UPDATE.
-- Uses AdventureWorks
UPDATE DimProduct
SET ProductSubcategoryKey = 2
WHERE ProductKey = 313
OPTION (LABEL = N'label1');
AG. Použití příkazu UPDATE 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é
VYTVOŘIT TABULKU (Transact-SQL)
VYTVOŘIT SPOUŠŤ (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