UPDATE (Transact-SQL)

Modifie des données existantes dans une ou plusieurs colonnes d'une table ou d'une vue dans SQL Server 2008 R2. Pour obtenir des exemples, consultez Exemples.

Icône Lien de rubriqueConventions 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 de l'expression de table commune est dérivé d'une simple requête et est référencé par l'instruction UPDATE. Pour plus d'informations, consultez WITH common_table_expression (Transact-SQL).

  • TOP ( expression**)** [ PERCENT ]
    Spécifie le nombre ou le pourcentage de lignes à mettre à jour. expression peut être soit un nombre, soit un pourcentage de lignes.

    Les lignes référencées dans l'expression TOP qui est utilisée avec INSERT, UPDATE, MERGE ou DELETE ne sont disposées dans aucun ordre particulier.

    Les parenthèses qui entourent expression dans l'expression TOP sont obligatoires dans les instructions INSERT, UPDATE, MERGE 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 lié sur lequel se trouve la table ou la vue. server_name peut être spécifié en tant que nom de serveur lié ou à l'aide de la fonction OPENDATASOURCE.

    Lorsque server_name est spécifié en tant que serveur lié, database_name et schema_name sont obligatoires. Lorsque server_name est spécifié avec OPENDATASOURCE, database_name et schema_name peuvent ne pas s'appliquer à toutes les sources de données ; par ailleurs, ils dépendent des fonctionnalités du fournisseur OLE DB qui accède à l'objet distant. Pour plus d'informations, consultez Requêtes distribuées.

  • database_name
    Nom de la base de données.

  • schema_name
    Nom du schéma auquel la table ou la vue appartient.

  • 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
    Fonction OPENQUERY ou OPENROWSET. L'utilisation de ces fonctions dépend des fonctionnalités du fournisseur OLE DB qui accède à l'objet distant. Pour plus d'informations, consultez Requêtes distribuées.

  • 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.

    Notes

    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

    Pour plus d'informations, consultez Opérateurs composés (Transact-SQL).

  • udt_column_name
    Colonne de type défini 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 de 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 sur 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 du 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 qui a un déclencheur INSTEAD OF UPDATE ne peut pas servir de cible à une instruction UPDATE avec une clause FROM.

    Notes

    Tout appel à OPENDATASOURCE, OPENQUERY ou OPENROWSET dans la clause FROM est évalué séparément et indépendamment de tout appel à ces fonctions utilisées 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é.

  • GLOBAL
    Précise 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 mondial 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 de curseur. cursor_variable_name doit faire référence à un curseur autorisant 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).

Meilleures pratiques

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.

Utilisez l'avertissement 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. Ceci peut engendrer des résultats inattendus. 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 AdventureWorks2008R2;
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 AdventureWorks2008R2;
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é

SET ROWCOUNT n'affectera en rien les instructions DELETE, INSERT et UPDATE dans la prochaine version de SQL Server. N'utilisez pas SET ROWCOUNT avec les instructions DELETE, INSERT et UPDATE dans les nouvelles tâches de développement et pensez à modifier les applications qui l'utilisent actuellement. Nous vous recommandons d'utiliser la syntaxe TOP.

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 des connexions. Pour plus d'informations, consultez SET ANSI_PADDING (Transact-SQL).

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.

Pour optimiser les performances, nous recommandons l'insertion ou la mise à jour de données en blocs multiples de 8 040 octets.

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 (jeu de caractères codés sur deux 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.

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 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 Vue d'ensemble de FILESTREAM.

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. Si l'instruction UPDATE peut modifier plusieurs lignes lors de la mise à jour de la clé de clustering et d'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.

Pour remplacer ou modifier des blocs volumineux de données text, ntext ou image, utilisez WRITETEXT ou UPDATETEXT plutôt que l'instruction UPDATE.

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 de données nvarchar(max), varchar(max) et varbinary(max). Pour plus d'informations, consultez Utilisation de types de données de valeur élevée.

Gestion des erreurs

Vous pouvez implémenter la gestion des erreurs pour l'instruction UPDATE en spécifiant cette dernière dans une construction TRY…CATCH. Pour plus d'informations, consultez Utilisation de TRY...CATCH dans Transact-SQL.

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.

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).

La définition de l'option SET ROWCOUNT est ignorée pour les instructions UPDATE en ce qui concerne les tables distantes et les vues partitionnées locales et distantes.

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 entraîner un comportement de jointure et des résultats de requête inattendus. Les exemples suivants illustrent l'utilisation de méthodes correctes et incorrectes en matière de spécification d'une expression de table commune 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 journalisation

L'instruction UPDATE est entièrement journalisée ; cependant, 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 lorsque .WRITE sert à mettre à jour des valeurs existantes. Pour plus d'informations, consultez Opérations pouvant faire l'objet d'une journalisation minimale.

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 sont attribuées par défaut aux membres du rôle serveur fixe sysadmin, aux membres des rôles de base de données fixes db_owner et db_datawriter, ainsi qu'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 des 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 de 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

OUTPUT (clause)

Utilisation de l'instruction 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 AdventureWorks2008R2;
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 dans la table SalesPerson.

USE AdventureWorks2008R2;
GO
UPDATE Sales.SalesPerson
SET Bonus = 6000, CommissionPct = .10, SalesQuota = NULL;
GO

Limitation des lignes mises à jour

Les exemples de cette section illustrent les 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 qui ont une valeur dans la colonne Name qui commence par 'Road-250'.

USE AdventureWorks2008R2;
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 AdventureWorks2008R2;
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ées 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. Pour plus d'informations sur les expressions de tables communes récursives, consultez Requêtes récursives utilisant des expressions de table communes.

USE AdventureWorks2008R2;
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 uniquement à jour 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 AdventureWorks2008R2;
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 de 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 AdventureWorks2008R2 ;
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 AdventureWorks2008R2;
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 AdventureWorks2008R2;
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 afin de déterminer la valeur utilisée pour mettre à jour la colonne. La sous-requête doit uniquement retourner 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 AdventureWorks2008R2;
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 de 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 AdventureWorks2008R2;
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 vue, un alias de table ou une variable de table.

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 aboutit car elle référence des colonnes d'une seule des tables sous-jacentes. L'instruction UPDATE échouerait si les colonnes des deux tables étaient spécifiées. Pour plus d'informations, consultez Modification de données par l'intermédiaire d'une vue.

USE AdventureWorks2008R2;
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 AdventureWorks2008R2;
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 AdventureWorks2008R2;
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 des 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 figurant 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 AdventureWorks2008R2;
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 AdventureWorks2008R2;
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'AdventureWorks2008R2';
GO
USE AdventureWorks2008R2;
GO
-- Specify the remote data source using a four-part name 
-- in the form linked_server.catalog.schema.object.

UPDATE MyLinkServer.AdventureWorks.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 Option Requêtes distribuées appropriées.

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 AdventureWorks2008R2;
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 AdventureWorks2008R2;
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 dans la colonne. Cet exemple suppose qu'un fichier nommé Tires.jpg existe dans le chemin d'accès spécifié.

USE AdventureWorks2008R2;
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 ne recommandons pas cette méthode pour transmettre en continu des 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 Vue d'ensemble de FILESTREAM.

UPDATE Archive.dbo.Records
SET [Chart] = CAST('Xray 1' as varbinary(max))
WHERE [SerialNumber] = 2;

Mise à jour de 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 de type Point appelée 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.

AttentionAttention

É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 utilise 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 AdventureWorks2008R2;
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êteOPTIMIZE 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 AdventureWorks2008R2;
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 à hauteur de 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 et 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 AdventureWorks2008R2;
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 d'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é à 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 AdventureWorks2008R2;
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 les erreurs d'exécution qui peuvent se produire au cours d'une opération de mise à jour. Pour plus d'informations, consultez Utilisation de TRY...CATCH dans Transact-SQL.

USE AdventureWorks2008R2;
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