UPDATE (Transact-SQL)
Modifie les données existantes d'une table ou d'une vue dans SQL Server 2012. Pour obtenir des exemples, consultez Exemples.
Conventions de la syntaxe Transact-SQL
Syntaxe
[ 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}
Arguments
WITH <common_table_expression>
Spécifie l'ensemble de résultats ou la vue nommés temporaires, également appelés expression de table commune (CTE) et définis dans le cadre de l'instruction UPDATE. Le jeu de résultats CTE est dérivé d'une simple requête et l'instruction UPDATE y fait référence.Vous pouvez également utiliser des expressions de table courantes avec les instructions SELECT, INSERT, DELETE et CREATE VIEW. Pour plus d'informations, consultez WITH common_table_expression (Transact-SQL).
TOP ( expression**)** [ PERCENT ]
Spécifie le nombre ou le pourcentage de lignes qui seront mises à jour. L'argument expression peut être un nombre ou un pourcentage de lignes.Les lignes référencées dans l'expression TOP utilisée dans les instructions INSERT, UPDATE ou DELETE ne sont pas triées dans un ordre précis.
Les parenthèses délimitant expression dans TOP sont nécessaires dans les instructions INSERT, UPDATE et DELETE. Pour plus d'informations, consultez TOP (Transact-SQL).
table_alias
Alias spécifié dans la clause FROM représentant la table ou la vue à partir de laquelle les lignes doivent être mises à jour.server_name
Nom du serveur (avec un nom de serveur lié ou la fonction OPENDATASOURCE en tant que nom de serveur) contenant la table ou la vue. Si server_name est spécifié, database_name et schema_name sont obligatoires.database_name
Nom de la base de données.schema_name
Nom du schéma auquel appartient la table ou la vue.table_or view_name
Nom de la table ou de la vue à partir de laquelle les lignes doivent être mises à jour. La vue, à laquelle fait référence table_or_view_name, doit pouvoir être mise à jour et faire référence exactement à une table de base dans sa clause FROM. Pour plus d'informations sur les vues pouvant être mises à jour, consultez CREATE VIEW (Transact-SQL).rowset_function_limited
Fonctions OPENQUERY ou OPENROWSET, en fonction des possibilités du fournisseur.WITH ( <Table_Hint_Limited> )
Spécifie un ou plusieurs indicateurs de table autorisés pour une table cible. Le mot clé WITH et les parenthèses sont obligatoires. NOLOCK et READUNCOMMITTED ne sont pas autorisés. Pour plus d'informations sur les indicateurs de table, consultez Indicateurs de table (Transact-SQL).@table\_variable
Spécifie une variable de table comme source de table.SET
Spécifie la liste des noms des colonnes ou des variables à mettre à jour.column_name
Colonne qui contient les données à modifier. column_name doit exister dans table_or view_name. Il est impossible de mettre à jour les colonnes d'identité.expression
Variable, valeur littérale, expression ou sous-instruction SELECT (entre parenthèses) retournant une valeur unique. La valeur retournée par expression remplace la valeur existante de column_name ou de @variable.[!REMARQUE]
Lorsque vous faites référence aux types de données character Unicode nchar, nvarchar et ntext, l'expression doit comporter la majuscule « N » en préfixe. Si vous ne spécifiez pas « N », SQL Server convertit la chaîne dans la page de codes qui correspond au classement par défaut de la base de données ou de la colonne. Tous les caractères absents de cette page de codes sont alors perdus.
DEFAULT
Spécifie que la valeur par défaut définie pour la colonne doit remplacer la valeur actuelle de la colonne. Cet argument peut également être utilisé pour attribuer la valeur NULL à la colonne si celle-ci n'a pas de valeur par défaut et autorise les valeurs NULL.{ += | -= | *= | /= | %= | &= | ^= | |= }
Opérateur d'assignation composé :+= Ajouter et attribuer
-= Soustraire et attribuer
*= Multiplier et attribuer
/= Diviser et attribuer
%= Modulo et attribuer
&= AND au niveau du bit et attribuer
^= XOR au niveau du bit et attribuer
|= OR au niveau du bit et attribuer
udt_column_name
Colonne définie par l'utilisateur.property_name | field_name
Propriété publique ou membre de données public d'un type défini par l'utilisateur.method_name**(**argument [ ,... n] )
Méthode du mutateur public non statique de udt_column_name qui prend au moins un argument..WRITE (expression,@Offset,@Length**)**
Indique qu'une section de la valeur de column_name doit être modifiée. expression remplace les unités @Length à partir de @Offset de column_name. Seules les colonnes de varchar(max), nvarchar(max) ou varbinary(max) peuvent être spécifiées avec cette clause. column_name ne peut pas avoir la valeur NULL et ne peut pas être qualifié avec un nom ou un alias de table.expression est la valeur copiée dans column_name. expression doit être du même type que column_name ou implicitement convertible vers celui-ci. Si expression prend la valeur NULL, @Length est ignoré, et la valeur dans column_name est tronquée au @Offset spécifié.
@Offset est le point de départ dans la valeur de column_name sur laquelle est rédigée expression. @Offset est une position ordinale calculée à partir de zéro, de type bigint et ne peut pas être un nombre négatif. Si la valeur de @Offset est NULL, la mise à jour ajoute expression à la fin de la valeur de column_name existante et @Length est ignoré. Si @Offset est supérieur à la longueur de la valeur column_name, le moteur de base de données retourne une erreur. Si @Offset plus @Length dépassent la fin de la valeur sous-jacente dans la colonne, tout est supprimé jusqu'au dernier caractère de la valeur. Si @Offset plus LEN(expression) est supérieur à la taille sous-jacente déclarée, une erreur est générée.
@Length est la longueur de la section dans la colonne, à partir de @Offset, remplacée par expression. @Length est de type bigint et ne peut pas être un nombre négatif. Si la valeur de @Length est NULL, la mise à jour supprime toutes les données de@Offset jusqu'à la fin de la valeur de column_name.
Pour plus d'informations, consultez la section Notes.
**@**variable
Variable déclarée définie sur la valeur retournée par expression.SET **@**variable = column = expression définit la variable à la même valeur que la colonne. Ceci est différent de SET **@**variable = column, column = expression, qui définit la variable à la valeur de la colonne avant la mise à jour.
<OUTPUT_Clause>
Retourne des données mises à jour ou des expressions associées dans le cadre de l'opération UPDATE. La clause OUTPUT n'est pas prise en charge dans les instructions DML, qui ciblent les tables ou les vues distantes. Pour plus d'informations, consultez Clause OUTPUT (Transact-SQL).FROM <table_source>
Spécifie qu'une table, une vue ou une source de table dérivée sont utilisées pour fournir les valeurs destinées à servir de critères en vue de la mise à jour. Pour plus d'informations, consultez FROM (Transact-SQL).Si l'objet mis à jour est le même que l'objet de la clause FROM et s'il n'existe qu'une seule référence à cet objet de la clause FROM, un alias d'objet pourra être spécifié ou non. Si l'objet mis à jour apparaît plusieurs fois dans la clause FROM, l'une des références, mais une seule, à cet objet ne doit pas spécifier un alias de la table. Toutes les autres références à l'objet dans la clause FROM doivent inclure un alias d'objet.
Une vue avec un déclencheur INSTEAD OF UPDATE ne peut pas servir de cible à une instruction UPDATE avec une clause FROM.
[!REMARQUE]
Tout appel à OPENDATASOURCE, OPENQUERY ou OPENROWSET dans la clause FROM est évalué séparément et indépendamment de tout appel à ces fonctions utilisé comme cible de la mise à jour, même si des arguments identiques sont fournis aux deux appels. En particulier, les conditions de filtre ou de jointure appliquées sur le résultat de l'un de ces appels n'ont aucun effet sur les résultats de l'autre.
WHERE
Spécifie les conditions de limite des lignes mises à jour. Il existe deux formes de mise à jour en fonction du contenu de la clause WHERE :Les mises à jour avec recherche comportent une condition de recherche pour qualifier les lignes à supprimer.
Les mises à jour avec positions utilisent la clause CURRENT OF pour définir un curseur. La mise à jour se produit à l'emplacement actuel du curseur.
<search_condition>
Spécifie la condition à remplir pour mettre à jour les lignes. La condition de recherche peut également être la condition sur laquelle est basée une jointure. Le nombre de prédicats inclus dans une condition de recherche est illimité. Pour plus d'informations sur les prédicats et les critères de recherche, consultez Condition de recherche (Transact-SQL).CURRENT OF
Spécifie que la mise à jour s'effectue à l'emplacement actuel du curseur spécifié.Une mise à jour positionnée utilisant une clause WHERE CURRENT OF met à jour uniquement la ligne sur laquelle est positionné le curseur. Cette opération peut s'avérer plus précise qu'une mise à jour avec recherche utilisant une clause WHERE <search_condition> pour qualifier les lignes à mettre à jour. Une mise à jour avec recherche modifie plusieurs lignes dès lors que la condition de recherche n'identifie pas de manière unique une seule ligne.
GLOBAL
Indique que cursor_name fait référence à un curseur global.cursor_name
Nom du curseur ouvert grâce auquel s'effectue l'extraction. Si un curseur global et un curseur local portent tous les deux le nom cursor_name, cet argument fait référence au curseur global si GLOBAL est précisé, et au curseur local dans tous les autres cas. Le curseur doit pouvoir gérer les mises à jour.cursor_variable_name
Nom d'une variable curseur. cursor_variable_name doit référencer un curseur qui autorise les mises à jour.OPTION ( <query_hint> [ ,... n ] )
Spécifie que des indicateurs d'optimiseur sont utilisés pour personnaliser le mode de traitement de l'instruction par le moteur de base de données. Pour plus d'informations, consultez Indicateurs de requête (Transact-SQL).
Recommandations
Utilisez la fonction @@ROWCOUNT pour retourner le nombre de lignes insérées dans l'application cliente. Pour plus d'informations, consultez @@ROWCOUNT (Transact-SQL).
Vous pouvez utiliser des noms de variables dans les instructions UPDATE pour présenter les anciennes et les nouvelles valeurs affectées, mais ceci n'est applicable que si l'instruction UPDATE n'affecte qu'un seul enregistrement. Si l'instruction UPDATE affecte plusieurs enregistrements, pour retourner les anciennes et les nouvelles valeurs pour chacun d'eux, utilisez la clause OUTPUT.
Soyez vigilant lors de la spécification de la clause FROM pour fournir les valeurs destinées à servir de critères en vue de la mise à jour. Les résultats d'une instruction UPDATE ne sont pas définis si celle-ci comprend une clause FROM qui ne spécifie pas qu'une seule valeur doit être disponible pour chaque occurrence de colonne mise à jour ; à savoir, si l'instruction UPDATE n'est pas déterministe. Par exemple, étant donné l'instruction UPDATE dans le script suivant, les deux lignes dans Table1 correspondent aux qualifications de la clause FROM dans l'instruction UPDATE, mais il n'y a aucune précision quant à savoir quelle ligne de Table1 est utilisée pour mettre à jour la ligne de Table2.
USE AdventureWorks2012;
GO
IF OBJECT_ID ('dbo.Table1', 'U') IS NOT NULL
DROP TABLE dbo.Table1;
GO
IF OBJECT_ID ('dbo.Table2', 'U') IS NOT NULL
DROP TABLE dbo.Table2;
GO
CREATE TABLE dbo.Table1
(ColA int NOT NULL, ColB decimal(10,3) NOT NULL);
GO
CREATE TABLE dbo.Table2
(ColA int PRIMARY KEY NOT NULL, ColB decimal(10,3) NOT NULL);
GO
INSERT INTO dbo.Table1 VALUES(1, 10.0), (1, 20.0);
INSERT INTO dbo.Table2 VALUES(1, 0.0);
GO
UPDATE dbo.Table2
SET dbo.Table2.ColB = dbo.Table2.ColB + dbo.Table1.ColB
FROM dbo.Table2
INNER JOIN dbo.Table1
ON (dbo.Table2.ColA = dbo.Table1.ColA);
GO
SELECT ColA, ColB
FROM dbo.Table2;
Le même problème peut avoir lieu lors de la combinaison des deux clauses FROM et WHERE CURRENT OF. Dans cet exemple, les deux lignes de Table2 correspondent aux qualifications de la clause FROM de l'instruction UPDATE. Aucune précision n'est fournie quant à savoir quelle ligne de Table2 est utilisée pour mettre à jour la ligne de Table1.
USE AdventureWorks2012;
GO
IF OBJECT_ID ('dbo.Table1', 'U') IS NOT NULL
DROP TABLE dbo.Table1;
GO
IF OBJECT_ID ('dbo.Table2', 'U') IS NOT NULL
DROP TABLE dbo.Table2;
GO
CREATE TABLE dbo.Table1
(c1 int PRIMARY KEY NOT NULL, c2 int NOT NULL);
GO
CREATE TABLE dbo.Table2
(d1 int PRIMARY KEY NOT NULL, d2 int NOT NULL);
GO
INSERT INTO dbo.Table1 VALUES (1, 10);
INSERT INTO dbo.Table2 VALUES (1, 20), (2, 30);
GO
DECLARE abc CURSOR LOCAL FOR
SELECT c1, c2
FROM dbo.Table1;
OPEN abc;
FETCH abc;
UPDATE dbo.Table1
SET c2 = c2 + d2
FROM dbo.Table2
WHERE CURRENT OF abc;
GO
SELECT c1, c2 FROM dbo.Table1;
GO
Prise en charge de la compatibilité
La prise en charge des indicateurs READUNCOMMITTED et NOLOCK dans la clause FROM s'appliquant à la table cible d'une instruction UPDATE ou DELETE sera supprimée dans une version future de SQL Server. Évitez d'utiliser ces indicateurs dans ce contexte lors de vos nouvelles tâches de développement, et pensez à modifier les applications qui les utilisent actuellement.
Types de données
Toutes les colonnes char et nchar sont complétées par des espaces à droite jusqu'à la longueur définie.
Si l'option ANSI_PADDING est désactivée (OFF), tous les espaces à droite sont supprimés des données insérées dans les colonnes varchar et nvarchar, sauf dans les chaînes ne contenant que des espaces. Ces chaînes sont tronquées en une chaîne vide. Si l'option ANSI_PADDING est activée (ON), des espaces supplémentaires sont insérés. Au moment de la connexion, le pilote ODBC de Microsoft SQL Server et le fournisseur OLE DB pour SQL Server attribuent automatiquement la valeur ON à SET ANSI_PADDING. Ceci peut être configuré dans les sources de données ODBC ou lors de la définition des attributs ou des propriétés de connexion. Pour plus d'informations, consultez SET ANSI_PADDING (Transact-SQL).
Mise à jour des colonnes de type text, ntext et image
La modification d'une colonne text, ntext ou image avec une instruction UPDATE initialise la colonne, lui affecte un pointeur de texte valide et lui alloue au moins une page de données, sauf si la colonne est mise à jour avec des valeurs NULL.
Pour remplacer ou modifier des blocs volumineux de données text, ntext ou image, utilisez WRITETEXT ou UPDATETEXT plutôt que l'instruction UPDATE.
Si l'instruction UPDATE peut modifier plusieurs lignes tout en mettant à jour la clé de clustering et une ou plusieurs colonnes text, ntext ou image, la mise à jour partielle de ces colonnes est exécutée en remplaçant toutes ces valeurs.
Important
Les types de données ntext, text et image seront supprimés dans une prochaine version de Microsoft SQL Server. Évitez par conséquent d'utiliser ces types de données dans les nouveaux travaux de développement et envisagez de modifier les applications qui les utilisent actuellement. Utilisez à la place les types nvarchar(max), varchar(max) et varbinary(max).
Mise à jour des données de valeurs élevées
Utilisez la clause .WRITE (expression, @Offset**,** @Length) pour effectuer une mise à jour partielle ou complète des types de données varchar(max), nvarchar(max) et varbinary(max). Par exemple, une mise à jour partielle d'une colonne varchar(max) risque de supprimer ou de modifier uniquement les 200 premiers caractères de la colonne, alors qu'une mise à jour complète supprime ou modifie toutes les données de cette colonne. .Les mises à jour WRITE, qui insèrent ou ajoutent de nouvelles données, sont journalisées de façon minimale si le mode de récupération des bases de données est défini comme étant simple ou utilisant les journaux de transactions. La journalisation minimale n'est pas utilisée lors de la mise à jour de valeurs existantes. Pour plus d'informations, consultez Journal des transactions (SQL Server).
Le moteur de base de données convertit une mise à jour partielle en mise à jour complète lorsque l'instruction UPDATE provoque l'une des actions suivantes :
Modification d'une colonne clé de la vue ou table partitionnée.
Modification de plusieurs lignes et mise à jour de la clé d'un index cluster non unique sur une valeur non constante.
Vous ne pouvez pas utiliser la clause **.**WRITE pour mettre à jour une colonne NULL ou définir la valeur de column_name sur NULL.
@Offset et @Length sont spécifiés en octets pour les types de données varbinary et varchar, et en caractères pour le type de données nvarchar. Les décalages appropriés sont calculés pour les classements DBCS.
Pour optimiser les performances, nous recommandons l'insertion ou la mise à jour de données en blocs multiples de 8 040 octets.
Si dans une clause OUTPUT, il est fait référence à la colonne modifiée par la clause **.**WRITE, la valeur complète de cette colonne, que ce soit l'image avant dans **deleted.**column_name ou l'image après dans **inserted.**column_name, est retournée à la colonne spécifiée dans la variable de table. Consultez l'exemple G ci-dessous.
Pour bénéficier de la même fonctionnalité de **.**WRITE avec des données de type caractère ou binaire, utilisez STUFF (Transact-SQL).
Mise à jour des colonnes définies par l'utilisateur
La mise à jour des valeurs dans des colonnes de type défini par l'utilisateur peut s'effectuer de l'une des façons suivantes :
Fournir une valeur dans un type de données système SQL Server, à condition que le type défini par l'utilisateur prenne en charge la conversion de façon implicite ou explicite. L'exemple suivant indique comment mettre à jour une valeur dans une colonne définie par l'utilisateur Point, en la convertissant explicitement à partir d'une chaîne.
UPDATE Cities SET Location = CONVERT(Point, '12.3:46.2') WHERE Name = 'Anchorage';
Appeler une méthode, marquée comme mutateur, d'un type défini par l'utilisateur, pour procéder à la mise à jour. L'exemple suivant appelle une méthode de mutateur du type Point appelé SetXY. L'état de l'instance de ce type est mis à jour.
UPDATE Cities SET Location.SetXY(23.5, 23.5) WHERE Name = 'Anchorage';
[!REMARQUE]
SQL Server retourne une erreur si une méthode mutateur est appelée sur une valeur NULL Transact-SQL ou si une nouvelle valeur produite par une méthode mutateur est NULL.
Modifier la valeur d'une propriété enregistrée ou d'un membre de données public, défini par l'utilisateur. L'expression qui fournit la valeur doit être implicitement convertible au type de propriété. L'exemple suivant modifie la valeur de propriété X du type défini par l'utilisateur Point.
UPDATE Cities SET Location.X = 23.5 WHERE Name = 'Anchorage';
Pour modifier différentes propriétés d'une colonne du même type défini par l'utilisateur, vous devez émettre plusieurs instructions UPDATE ou appeler la méthode du mutateur correspondant à ce type.
Mise à jour de données FILESTREAM
Vous pouvez utiliser l'instruction UPDATE pour mettre à jour un champ FILESTREAM avec une valeur Null, une valeur vide ou une quantité relativement faible de données incluses. Toutefois, une grande quantité de données est diffusée en continu plus efficacement dans un fichier à l'aide des interfaces Win32. Lorsque vous mettez à jour un champ FILESTREAM, vous modifiez les données d'objet blob sous-jacentes dans le système de fichiers. Lorsqu'un champ FILESTREAM a la valeur NULL, les données d'objet blob associées au champ sont supprimées. Vous ne pouvez pas utiliser .WRITE(), pour appliquer des mises à jour partielles aux données FILESTREAM. Pour plus d'informations, consultez FILESTREAM (SQL Server).
Gestion des erreurs
Si la mise à jour d'une ligne enfreint une contrainte ou une règle, qu'elle viole le paramètre NULL de la colonne ou que la nouvelle valeur est d'un type de données incompatible, l'instruction est annulée, une erreur est retournée et aucun enregistrement n'est mis à jour.
Lorsqu'une instruction UPDATE rencontre une erreur arithmétique (erreur de dépassement de capacité, de division par zéro ou de domaine) lors de l'évaluation de l'expression, la mise à jour n'est pas effectuée. Le reste du traitement n'est pas exécuté et un message d'erreur est retourné.
Si la mise à jour d'une ou de plusieurs colonnes participant à un index cluster conduit à une taille d'index et de ligne supérieure à 8 060 octets, la mise à jour n'est pas effectuée et un message d'erreur est retourné.
Interopérabilité
Vous pouvez insérer des instructions UPDATE dans le corps des fonctions définies par l'utilisateur uniquement si la table en cours de modification est une variable de table.
Lorsqu'un déclencheur INSTEAD OF est défini sur des actions UPDATE appliquées à une table, il est exécuté à la place de l'instruction UPDATE. Les versions antérieures de SQL Server prennent uniquement en charge les déclencheurs AFTER définis sur UPDATE et autres instructions de modification de données. La clause FROM ne peut pas être spécifiée dans une instruction UPDATE qui fait référence, directement ou indirectement, à une vue sur laquelle est défini un déclencheur INSTEAD OF. Pour plus d'informations sur les déclencheurs INSTEAD OF, consultez CREATE TRIGGER (Transact-SQL).
Limitations et restrictions
La clause FROM ne peut pas être spécifiée dans une instruction UPDATE qui fait référence, directement ou indirectement, à une vue sur laquelle est défini un déclencheur INSTEAD OF. Pour plus d'informations sur les déclencheurs INSTEAD OF, consultez CREATE TRIGGER (Transact-SQL).
Lorsqu'une expression de table commune (CTE) est la cible d'une instruction UPDATE, toutes les références cette expression de table commune dans l'instruction doivent correspondre. Par exemple, si un alias est affecté à l'expression de table commune dans la clause FROM, cet alias doit être utilisé pour toutes les autres références à l'expression de table commune. Des références non ambiguës à l'expression de table commune sont requises, car une expression de table commune n'a pas d'ID d'objet, lequel est utilisé par SQL Server pour identifier la relation implicite entre un objet et son alias. Sans cette relation, le plan de requête peut donner lieu à un comportement de jointure inattendu et à des résultats de requête indésirables. Les exemples suivants montrent des méthodes correctes et incorrectes de spécification d'une expression CTE lorsque celle-ci est l'objet cible de l'opération de mise à jour.
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
Voici l'ensemble des résultats.
ID Value
------ -----
1 100
2 200
(2 row(s) affected)
-- UPDATE statement with CTE references that are incorrectly matched.
USE tempdb;
GO
DECLARE @x TABLE (ID int, Value int);
DECLARE @y TABLE (ID int, Value int);
INSERT @x VALUES (1, 10), (2, 20);
INSERT @y VALUES (1, 100),(2, 200);
WITH cte AS (SELECT * FROM @x)
UPDATE cte -- cte is not referenced by the alias.
SET Value = y.Value
FROM cte AS x -- cte is assigned an alias.
INNER JOIN @y AS y ON y.ID = x.ID;
SELECT * FROM @x;
GO
Voici l'ensemble des résultats.
ID Value
------ -----
1 100
2 100
(2 row(s) affected)
Comportement de verrouillage
Une instruction UPDATE acquiert toujours un verrou exclusif (X) sur la table qu'elle modifie et maintient ce verrou jusqu'à la fin de la transaction. Avec un verrou exclusif, aucune autre transaction ne peut modifier des données. Vous pouvez spécifier des indicateurs de table pour remplacer ce comportement par défaut pour la durée de l'instruction UPDATE en spécifiant une autre méthode de verrouillage ; toutefois, nous vous recommandons de ne recourir aux indicateurs qu'en dernier ressort et seulement si vous êtes un développeur ou un administrateur de base de données expérimenté. Pour plus d'informations, consultez Indicateurs de table (Transact-SQL).
Comportement de journalisation
L'instruction UPDATE est consignée dans le journal. Cependant, les mises à jour partielles aux données de valeurs élevées utilisant la clause **.**WRITE sont journalisées de façon minimale. Pour plus d'informations, consultez la rubrique « Mise à jour des données de valeurs élevées » de la section précédente « Types de données ».
Sécurité
Autorisations
Les autorisations UPDATE sont obligatoires sur la table cible. Les autorisations SELECT sont également obligatoires pour la table en cours de mise à jour si l'instruction UPDATE contient une clause WHERE ou si expression dans la clause SET utilise une colonne de la table.
Les autorisations UPDATE reviennent par défaut aux membres du rôle serveur fixe sysadmin, aux rôles de base de données fixes db_owner et db_datawriter et au propriétaire de la table. Les membres des rôles sysadmin, db_owner et db_securityadmin, ainsi que le propriétaire de la table peuvent transférer des autorisations à d'autres utilisateurs.
Exemples
Catégorie |
Éléments syntaxiques proposés |
---|---|
Syntaxe de base |
UPDATE |
Limitation des lignes mises à jour |
WHERE • TOP • WITH expression de table commune • WHERE CURRENT OF |
Définition des valeurs de colonne |
valeurs calculées • opérateurs composés • valeurs par défaut • sous-requêtes |
Spécification d'objets cibles autres que les tables standard |
vues • variables de table • alias de table |
Mise à jour de données selon les données d'autres tables |
FROM |
Mise à jour de lignes dans une table distante |
serveur lié • OPENQUERY • OPENDATASOURCE |
Mise à jour de types de données LOB (objets volumineux) |
.WRITE • OPENROWSET |
Mise à jour des types définis par l'utilisateur |
types définis par l'utilisateur |
Substitution du comportement par défaut de l'optimiseur de requête à l'aide d'indicateurs |
indicateurs de table • indicateurs de requête |
Capture des résultats de l'instruction UPDATE |
Clause OUTPUT |
Utilisation d'UPDATE dans d'autres instructions |
Procédures stockées • TRY…CATCH |
Syntaxe de base
Les exemples fournis dans cette section présentent les fonctionnalités de base de l'instruction UPDATE en utilisant la syntaxe minimale requise.
A.Utilisation d'une instruction UPDATE simple
L'exemple suivant met à jour une colonne unique pour toutes les lignes de la table Person.Address.
USE AdventureWorks2012;
GO
UPDATE Person.Address
SET ModifiedDate = GETDATE();
B.Mise à jour de plusieurs colonnes
L'exemple suivant met à jour les valeurs dans les colonnes Bonus, CommissionPct et SalesQuota pour toutes les lignes de la table SalesPerson.
USE AdventureWorks2012;
GO
UPDATE Sales.SalesPerson
SET Bonus = 6000, CommissionPct = .10, SalesQuota = NULL;
GO
Limitation des lignes mises à jour
Les exemples de cette section montrent les différentes méthodes que vous pouvez utiliser pour limiter le nombre de lignes affectées par l'instruction UPDATE.
A.Utilisation de la clause WHERE
L'exemple suivant utilise la clause WHERE pour spécifier quelles lignes mettre à jour. L'instruction met à jour la valeur dans la colonne Color de la table Production.Product pour toutes les lignes qui ont une valeur existante de « Red » (rouge) dans la colonne Color et ont une valeur dans la colonne Name qui commence par « Road-250 ».
USE AdventureWorks2012;
GO
UPDATE Production.Product
SET Color = N'Metallic Red'
WHERE Name LIKE N'Road-250%' AND Color = N'Red';
GO
B.Utilisation de la clause TOP
Les exemples suivants utilisent la clause TOP pour limiter le nombre de lignes modifiées dans une instruction UPDATE. Lorsqu'une clause TOP (n) est utilisée avec UPDATE, l'opération de mise à jour est effectuée sur une sélection aléatoire de « n » lignes. L'exemple suivant met à jour la colonne VacationHours à hauteur de 25 % pour 10 lignes aléatoires dans la table Employee.
USE AdventureWorks2012;
GO
UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25 ;
GO
Si vous devez utiliser la clause TOP pour appliquer des mises à jour en respectant une certaine chronologie, vous devez combiner les clauses TOP et ORDER BY dans une instruction de sous-sélection. L'exemple ci-dessous met à jour les heures de congé des 10 employés dont la date d'embauche est la plus ancienne.
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
C.Utilisation de la clause WITH common_table_expression
L'exemple suivant met à jour la valeur PerAssemnblyQty pour l'ensemble des parties et des composants utilisés directement ou indirectement pour créer ProductAssemblyID 800. L'expression de table commune retourne une liste hiérarchique des parties utilisées directement pour générer ProductAssemblyID 800 et des parties utilisés pour générer ces composants, et ainsi de suite. Seules les lignes renvoyées par l'expression de table commune récursive sont modifiées.
USE AdventureWorks2012;
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;
D.Utilisation de la clause WHERE CURRENT OF
L'exemple suivant utilise la clause WHERE CURRENT OF pour mettre à jour uniquement la ligne sur laquelle le curseur est positionné. Dans le cas d'un curseur basé sur une jointure, seul le paramètre table_name spécifié dans l'instruction UPDATE est modifié. Les autres tables participant au curseur ne sont pas affectées.
USE AdventureWorks2012;
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
Définition des valeurs de colonne
Les exemples de cette section illustrent la mise à jour de colonnes à l'aide de valeurs calculées, de sous-requêtes et des valeurs DEFAULT.
A.Spécification d'une valeur calculée
Les exemples suivants utilisent des valeurs calculées dans une instruction UPDATE. Cet exemple double la valeur dans la colonne ListPrice pour toutes les lignes de la table Product.
USE AdventureWorks2012 ;
GO
UPDATE Production.Product
SET ListPrice = ListPrice * 2;
GO
B.Spécification d'un opérateur composé
L'exemple suivant utilise la variable @NewPrice pour incrémenter le prix de toutes les bicyclettes rouges en prenant le prix actuel et en lui ajoutant 10.
USE AdventureWorks2012;
GO
DECLARE @NewPrice int = 10;
UPDATE Production.Product
SET ListPrice += @NewPrice
WHERE Color = N'Red';
GO
L'exemple suivant utilise l'opérateur composé += pour ajouter les données ' - tool malfunction' à la valeur existante dans la colonne Name pour les lignes qui ont un ScrapReasonID compris entre 10 et 12.
USE AdventureWorks2012;
GO
UPDATE Production.ScrapReason
SET Name += ' - tool malfunction'
WHERE ScrapReasonID BETWEEN 10 and 12;
C.Spécification d'une sous-requête dans la clause SET
L'exemple suivant utilise une sous-requête dans la clause SET pour déterminer la valeur utilisée pour mettre à jour la colonne. La sous-requête doit retourner uniquement une valeur scalaire (autrement dit, une valeur unique par ligne). Cet exemple modifie la colonne SalesYTD dans la table SalesPerson pour illustrer les dernières ventes enregistrées dans la table SalesOrderHeader. La sous-requête agrège les ventes de chaque commercial dans l'instruction UPDATE.
USE AdventureWorks2012;
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
D.Mise à jour de lignes à l'aide des valeurs DEFAULT
L'exemple suivant définit la colonne CostRate sur sa valeur par défaut (0.00) pour toutes les lignes qui ont une valeur CostRate supérieure à 20.00.
USE AdventureWorks2012;
GO
UPDATE Production.Location
SET CostRate = DEFAULT
WHERE CostRate > 20.00;
Spécification d'objets cibles autres que les tables standard
Les exemples présentés dans cette section montrent comment mettre à jour des lignes en spécifiant une variable de table, un alias de table ou une vue.
A.Spécification d'une vue comme objet cible
L'exemple suivant met à jour des lignes dans une table en spécifiant une vue comme objet cible. La définition de la vue référence plusieurs tables. Toutefois, l'instruction UPDATE réussit car elle référence des colonnes d'une seule des tables sous-jacentes. L'instruction UPDATE échouerait si des colonnes des deux tables étaient spécifiées. Pour plus d'informations, consultez Modifier les données par l'intermédiaire d'une vue.
USE AdventureWorks2012;
GO
UPDATE Person.vStateProvinceCountryRegion
SET CountryRegionName = 'United States of America'
WHERE CountryRegionName = 'United States';
B.Spécification d'un alias de table comme objet cible
L'exemple suivant met à jour des lignes dans la table Production.ScrapReason. L'alias de table affecté à ScrapReason dans la clause FROM est spécifié comme objet cible dans la clause UPDATE.
USE AdventureWorks2012;
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;
C.Spécification d'une variable de table comme objet cible
L'exemple suivant met à jour des lignes dans une variable de table.
USE AdventureWorks2012;
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
Mise à jour de données selon les données d'autres tables
Les exemples fournis dans cette section présentent des méthodes de mise à jour de lignes d'une table en fonction d'informations contenues dans une autre table.
A.Utilisation de l'instruction UPDATE avec des informations provenant d'une autre table
L'exemple suivant modifie la colonne SalesYTD dans la table SalesPerson pour illustrer les dernières ventes enregistrées dans la table SalesOrderHeader.
USE AdventureWorks2012;
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
L'exemple précédent suppose qu'une seule vente est enregistrée pour un vendeur particulier sur une date donnée et que les mises à jour sont actuelles. Cet exemple ne convient pas si plusieurs ventes peuvent être enregistrées pour un vendeur donné au cours d'une même journée. Il s'exécutera sans erreur, mais chaque valeur SalesYTD ne sera mise à jour qu'avec une seule vente, en dépit du nombre de ventes ayant réellement eu lieu ce jour-là. En effet, une instruction UPDATE ne met jamais une même ligne à jour à deux reprises.
Au cas où plusieurs ventes pourraient avoir lieu le même jour pour un commercial donné, toutes les ventes de chaque commercial doivent être agrégées dans l'instruction UPDATE, comme le montre l'exemple suivant :
USE AdventureWorks2012;
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
Mise à jour de lignes dans une table distante
Les exemples présentés dans cette section montrent comment mettre à jour des lignes dans une table cible distante en utilisant un serveur lié ou une fonction d'ensemble de lignes pour référencer la table distante.
A.Mise à jour de données dans une table distante en utilisant un serveur lié
L'exemple suivant met à jour une table sur un serveur distant. L'exemple commence par créer un lien vers la source de données distante en utilisant sp_addlinkedserver. Le nom du serveur lié, MyLinkServer, est ensuite spécifié dans un nom d'objet en quatre parties qui se présente sous la forme server.catalog.schema.object. Notez que vous devez spécifier un nom de serveur valide pour @datasrc.
USE master;
GO
-- Create a link to the remote data source.
-- Specify a valid server name for @datasrc as 'server_name' or 'server_name\instance_name'.
EXEC sp_addlinkedserver @server = N'MyLinkServer',
@srvproduct = N' ',
@provider = N'SQLNCLI10',
@datasrc = N'<server name>',
@catalog = N'AdventureWorks2012';
GO
USE AdventureWorks2012;
GO
-- Specify the remote data source using a four-part name
-- in the form linked_server.catalog.schema.object.
UPDATE MyLinkServer.AdventureWorks2012.HumanResources.Department
SET GroupName = N'Public Relations'
WHERE DepartmentID = 4;
B.Mise à jour de données dans une table distante en utilisant la fonction OPENQUERY
L'exemple suivant met à jour une ligne dans une table distante en spécifiant la fonction d'ensemble de lignes OPENQUERY. Le nom de serveur lié créé dans l'exemple précédent est utilisé dans cet exemple.
UPDATE OPENQUERY (MyLinkServer, 'SELECT GroupName FROM HumanResources.Department WHERE DepartmentID = 4')
SET GroupName = 'Sales and Marketing';
C.Mise à jour de données dans une table distante en utilisant la fonction OPENDATASOURCE
L'exemple suivant insère une ligne dans une table distante en spécifiant la fonction d'ensemble de lignes OPENDATASOURCE. Spécifiez un nom de serveur valide pour la source de données en utilisant le format server_name ou server_name\instance_name. Vous devrez peut-être configurer l'instance de SQL Server pour les requêtes distribuées appropriées. Pour plus d'informations, consultez Requêtes distribuées ad hoc activées (option de configuration de serveur).
UPDATE OPENQUERY (MyLinkServer, 'SELECT GroupName FROM HumanResources.Department WHERE DepartmentID = 4')
SET GroupName = 'Sales and Marketing';
Mise à jour de types de données LOB (objets volumineux)
Les exemples de cette section illustrent des méthodes de mise à jour de valeurs dans les colonnes définies avec les types de données LOB.
A.Utilisation de l'instruction UPDATE avec la clause .WRITE pour modifier les données dans une colonne nvarchar(max)
L'exemple suivant utilise la clause .WRITE pour mettre à jour une valeur partielle dans DocumentSummary, une colonne nvarchar(max) dans la table Production.Document . Le terme components est remplacé par le terme features, en spécifiant le terme de remplacement, l'emplacement de départ (décalage) du terme à remplacer dans les données existantes et le nombre de caractères à remplacer (longueur). L'exemple utilise également la clause OUTPUT pour retourner les images avant et après de la colonne DocumentSummary à la variable de table @MyTableVar.
USE AdventureWorks2012;
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
B.Utilisation de l'instruction UPDATE avec la clause .WRITE pour ajouter et supprimer des données dans une colonne nvarchar(max)
Les exemples suivants ajoutent et suppriment les données d'une colonne nvarchar(max) dont la valeur est actuellement définie sur NULL. Étant donné que la clause .WRITE ne peut pas être utilisée pour modifier une colonne NULL, celle-ci est d'abord renseignée avec des données provisoires. Ces données sont ensuite remplacées par les données appropriées à l'aide de la clause .WRITE. Les exemples supplémentaires ajoutent des données à la fin de la valeur de colonne, suppriment (tronquent) les données de la colonne et, pour finir, suppriment les données partielles de la colonne. Les instructions SELECT affichent la modification de données générée par chaque instruction UPDATE.
USE AdventureWorks2012;
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
C.Utilisation de l'instruction UPDATE avec OPENROWSET pour modifier une colonne varbinary(max)
L'exemple suivant remplace une image existante stockée dans une colonne varbinary(max) par une nouvelle image. La fonction OPENROWSET est utilisée en conjonction avec l'option BULK pour charger l'image sur la colonne. Cet exemple suppose qu'un fichier nommé Tires.jpg existe dans le chemin d'accès spécifié.
USE AdventureWorks2012;
GO
UPDATE Production.ProductPhoto
SET ThumbNailPhoto = (
SELECT *
FROM OPENROWSET(BULK 'c:\Tires.jpg', SINGLE_BLOB) AS x )
WHERE ProductPhotoID = 1;
GO
D.Utilisation de l'instruction UPDATE pour modifier des données FILESTREAM
L'exemple suivant utilise l'instruction UPDATE pour modifier les données dans le fichier de système de fichiers. Nous déconseillons cette méthode pour transmettre en continu de grandes quantités de données à un fichier. Utilisez les interfaces Win32 appropriées. L'exemple suivant remplace tout texte dans l'enregistrement de fichier par le texte Xray 1. Pour plus d'informations, consultez FILESTREAM (SQL Server).
UPDATE Archive.dbo.Records
SET [Chart] = CAST('Xray 1' as varbinary(max))
WHERE [SerialNumber] = 2;
Mise à jour des types définis par l'utilisateur
Les exemples suivants modifient des valeurs dans les colonnes de type clr défini par l'utilisateur (UDT). Trois méthodes sont illustrées. Pour plus d'informations sur les colonnes définies par l'utilisateur, consultez Types CLR définis par l'utilisateur.
A.Utilisation d'un type de données système
Vous pouvez mettre à jour un UDT en fournissant une valeur dans un type de données système SQL Server, à condition que le type défini par l'utilisateur prenne en charge la conversion de façon implicite ou explicite. L'exemple suivant indique comment mettre à jour une valeur dans une colonne définie par l'utilisateur Point, en la convertissant explicitement à partir d'une chaîne.
UPDATE dbo.Cities
SET Location = CONVERT(Point, '12.3:46.2')
WHERE Name = 'Anchorage';
B.Appel d'une méthode
Vous pouvez mettre à jour un UDT en appelant une méthode, marquée en tant que mutateur, du type défini par l'utilisateur afin d'effectuer la mise à jour. L'exemple suivant appelle une méthode de mutateur du type Point appelé SetXY. L'état de l'instance de ce type est mis à jour.
UPDATE dbo.Cities
SET Location.SetXY(23.5, 23.5)
WHERE Name = 'Anchorage';
C.Modification de la valeur d'une propriété ou d'un membre de données
Vous pouvez mettre à jour un UDT en modifiant la valeur d'une propriété inscrite ou d'un membre de données publiques du type défini par l'utilisateur. L'expression qui fournit la valeur doit être implicitement convertible au type de propriété. L'exemple suivant modifie la valeur de propriété X du type défini par l'utilisateur Point.
UPDATE dbo.Cities
SET Location.X = 23.5
WHERE Name = 'Anchorage';
Substitution du comportement par défaut de l'optimiseur de requête à l'aide d'indicateurs
Les exemples présentés dans cette section montrent comment utiliser des indicateurs de table et de requête pour substituer temporairement le comportement par défaut de l'optimiseur de requête lors du traitement de l'instruction UPDATE.
Attention |
---|
Étant donné que l'optimiseur de requête SQL Server sélectionne généralement le meilleur plan d'exécution pour une requête, nous vous recommandons de ne recourir aux indicateurs qu'en dernier ressort et seulement si vous êtes un développeur ou un administrateur de base de données expérimenté. |
A.Spécification d'un indicateur de table
L'exemple suivant spécifie l'indicateur de table TABLOCK. Cet indicateur spécifie qu'un verrou partagé est établi sur la table Production.Product et maintenu jusqu'à la fin de l'instruction UPDATE.
USE AdventureWorks2012;
GO
UPDATE Production.Product
WITH (TABLOCK)
SET ListPrice = ListPrice * 1.10
WHERE ProductNumber LIKE 'BK-%';
GO
B.Spécification d'un indicateur de requête
L'exemple suivant spécifie l'indicateur de requête OPTIMIZE FOR (@variable) dans l'instruction UPDATE. Cet indicateur spécifie à l'optimiseur de requête d'attribuer à une variable locale une valeur déterminée lors de la compilation et de l'optimisation de la requête. Cette valeur n'est utilisée que pendant l'optimisation de la requête, et non pas lors de son exécution.
USE AdventureWorks2012;
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-%';
Capture des résultats de l'instruction UPDATE
Les exemples présentés dans cette section montrent comment utiliser la clause OUTPUT pour retourner des informations de chaque ligne affectée par une instruction UPDATE, ou des expressions basées sur ces lignes. Ces résultats peuvent être retournés à l'application en cours de traitement afin d'être utilisés notamment avec des messages de confirmation, des opérations d'archivage et d'autres spécifications d'application similaires.
A.Utilisation de l'instruction UPDATE avec la clause OUTPUT
L'exemple suivant met à jour la colonne VacationHours dans la table Employee par 25 pour cent pour les 10 premières lignes et définit également la valeur dans la colonne ModifiedDate sur la date actuelle. La clause OUTPUT retourne la valeur de VacationHours qui existe avant l'application de l'instruction UPDATE dans la colonne deleted.VacationHours et la valeur mise à jour dans la colonne inserted.VacationHours sur la variable de table @MyTableVar.
Deux instructions SELECT suivent ; elles retournent les valeurs dans @MyTableVar, ainsi que les résultats de la mise à jour dans la table Employee. Pour plus d'exemples qui utilisent la clause OUTPUT, consultez Clause OUTPUT (Transact-SQL).
USE AdventureWorks2012;
GO
DECLARE @MyTableVar table(
EmpID int NOT NULL,
OldVacationHours int,
NewVacationHours int,
ModifiedDate datetime);
UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25,
ModifiedDate = GETDATE()
OUTPUT inserted.BusinessEntityID,
deleted.VacationHours,
inserted.VacationHours,
inserted.ModifiedDate
INTO @MyTableVar;
--Display the result set of the table variable.
SELECT EmpID, OldVacationHours, NewVacationHours, ModifiedDate
FROM @MyTableVar;
GO
--Display the result set of the table.
SELECT TOP (10) BusinessEntityID, VacationHours, ModifiedDate
FROM HumanResources.Employee;
GO
Utilisation de l'instruction UPDATE dans d'autres instructions
Les exemples de cette section montrent comment utiliser UPDATE dans d'autres instructions.
A.Utilisation de l'instruction UPDATE dans une procédure stockée
L'exemple ci-dessous utilise une instruction UPDATE dans une procédure stockée. La procédure accepte un paramètre d'entrée, @NewHours et un paramètre de sortie @RowCount. La valeur du paramètre @NewHours est utilisée dans l'instruction UPDATE pour mettre à jour la colonne VacationHours de la table HumanResources.Employee. Le paramètre de sortie @RowCount est utilisé pour retourner le nombre de lignes affectées à une variable locale. L'expression CASE est utilisée dans la clause SET pour déterminer de manière conditionnelle la valeur qui est définie pour VacationHours. Lorsque l'employé est payé à l'heure (SalariedFlag = 0), VacationHours est défini avec le nombre actuel d'heures plus la valeur spécifiée dans @NewHours ; sinon, VacationHours est défini avec la valeur spécifiée dans @NewHours.
USE AdventureWorks2012;
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;
B.Utilisation de l'instruction UPDATE dans un bloc TRY…CATCH
L'exemple suivant utilise une instruction UPDATE dans un bloc TRY…CATCH pour gérer des erreurs d'exécution qui peuvent se produire au cours d'une opération de mise à jour.
USE AdventureWorks2012;
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
Voir aussi
Référence
Fonctions texte et image (Transact-SQL)
WITH common_table_expression (Transact-SQL)