242 votes

Comment mettre à jour deux tables dans une déclaration en SQL Server 2005 ?

Je veux mettre à jour deux tables en une seule fois. Comment puis-je le faire dans SQL Server 2005 ?

UPDATE 
  Table1, 
  Table2
SET 
  Table1.LastName='DR. XXXXXX', 
  Table2.WAprrs='start,stop'
FROM 
  Table1 T1, 
  Table2 T2
WHERE 
  T1.id = T2.id
AND 
  T1.id = '010008'

4 votes

Il serait utile que vous expliquiez pourquoi.

2 votes

J'ai bien peur que le serveur SQL 2005 ne supporte pas la mise à jour de plusieurs tables en une seule requête.

0 votes

241voto

LBushkin Points 60611

Vous ne pouvez pas mettre à jour plusieurs tables en une seule déclaration, mais vous pouvez utiliser une transaction pour vous assurer que deux tables sont mises à jour. UPDATE sont traitées de manière atomique. Vous pouvez également les regrouper pour éviter un aller-retour.

BEGIN TRANSACTION;

UPDATE Table1
SET Table1.LastName = 'DR. XXXXXX' 
FROM Table1 T1, Table2 T2
WHERE T1.id = T2.id
and T1.id = '011008';

UPDATE Table2
SET Table2.WAprrs = 'start,stop'
FROM Table1 T1, Table2 T2
WHERE T1.id = T2.id
and T1.id = '011008';

COMMIT;

0 votes

En fait, je mets à jour les enregistrements de ces deux tables à partir d'un autre temptable. Le temptable a un lien vers la table 1 mais pas vers la table 2. Comment puis-je mettre à jour le même enregistrement de la Table2 ? Comment vais-je le lier ?

1 votes

@Inconnu : D'après votre commentaire, vous devez effectuer une jointure entre Table1 et Table2 lorsque vous mettez à jour Table2 si votre requête de mise à jour a besoin des clés d'une troisième table. Indépendamment de cela, vous devez toujours effectuer deux mises à jour distinctes.

3 votes

Probablement sans rapport : cela ne fonctionnera pas avec MYSQL car la syntaxe de mise à jour pour mysql est différente. Vous devriez faire UPDATE Table1 , Table2 SET Table1.LastName = 'DR. XXXXXX' WHERE T1.id = T2.id

114voto

Remus Rusanu Points 159382

Vous ne pouvez pas mettre à jour deux tables à la fois, mais vous pouvez lier une mise à jour à une insertion en utilisant la méthode suivante OUTPUT INTO et vous pouvez utiliser cette sortie comme jointure pour la deuxième mise à jour :

DECLARE @ids TABLE (id int);
BEGIN TRANSACTION

UPDATE Table1 
SET Table1.LastName = 'DR. XXXXXX'  
OUTPUT INSERTED.id INTO @ids
WHERE Table1.field = '010008';

UPDATE Table2 
SET Table2.WAprrs = 'start,stop' 
FROM Table2 
JOIN @ids i on i.id = Table2.id;

COMMIT;

J'ai changé votre exemple WHERE pour être un autre champ que id . Si c'est id le vous n'avez pas besoin de cette fantaisie OUTPUT vous pouvez juste UPDATE le deuxième tableau pour le même id='010008' .

2 votes

C'est la meilleure réponse et elle devrait être votée comme la vraie réponse à la question originale. Merci. Cela a fonctionné pour moi.

1 votes

Est-ce que T1.field censé être Table1.field ?

0 votes

Si vous vous demandez ce que signifie INSERTED dans "OUTPUT INSERTED.id", regardez ici : "INSERTED - Est un préfixe de colonne qui spécifie la valeur ajoutée par l'opération d'insertion ou de mise à jour. Les colonnes préfixées par INSERTED reflètent la valeur après la fin de l'instruction UPDATE, INSERT ou MERGE, mais avant l'exécution des triggers." lien : docs.microsoft.com/fr/us/sql/t-sql/queries/

26voto

Charles Bretana Points 59899

Désolé, à ce jour, vous ne pouvez pas faire ça. Pour mettre à jour des attributs dans deux tables différentes, vous devrez exécuter deux instructions distinctes. Mais elles peuvent être dans un batch ( un ensemble de SQL envoyé au serveur en un seul aller-retour )

2 votes

Mon Dieu ! Je devrais utiliser le mot "désolé" plus souvent pour avoir des félicitations supplémentaires :P

16voto

jveazey Points 2490

La réponse courte à cette question est non. Bien que vous puissiez saisir plusieurs tableaux dans le from d'une instruction de mise à jour, vous ne pouvez spécifier qu'une seule table après la clause update mot-clé. Même si vous écrivez une vue "actualisable" (qui est simplement une vue qui suit certaines restrictions), les mises à jour comme celle-ci échoueront. Voici les extraits pertinents de la documentation MSDN (c'est moi qui souligne).

UPDATE (Transact-SQL)

La vue référencée par table_ou_nom_de_la_vue doit pouvoir être mise à jour et référencée exactement une table de base dans la clause FROM de la vue. Pour plus d'informations sur les vues actualisables, voir CREATE VIEW (Transact-SQL).

CREATE VIEW (Transact-SQL)

Vous pouvez modifier les données d'une table de base sous-jacente par le biais d'une vue, pour autant que les conditions suivantes soient remplies :

  • Toute modification, y compris les instructions UPDATE, INSERT et DELETE, doit faire référence à des colonnes provenant de une seule table de base .
  • Les colonnes modifiées dans la vue doivent faire directement référence aux données sous-jacentes dans les colonnes de la table. Les colonnes ne peuvent pas être dérivées d'une autre manière, par exemple par le biais de ce qui suit :
    • Une fonction d'agrégation : AVG, COUNT, SUM, MIN, MAX, GROUPING, STDEV, STDEVP, VAR et VARP.
    • Un calcul. La colonne ne peut pas être calculée à partir d'une expression qui utilise d'autres colonnes. Les colonnes formées à l'aide des opérateurs d'ensemble UNION, UNION ALL, CROSSJOIN, EXCEPT et INTERSECT équivalent à un calcul et ne peuvent pas non plus être mises à jour.
  • Les colonnes en cours de modification ne sont pas affectées par les clauses GROUP BY, HAVING ou DISTINCT.
  • TOP n'est utilisé nulle part dans l'instruction select_statement de la vue avec la clause WITH CHECK OPTION.

En toute honnêteté, cependant, vous devriez envisager d'utiliser deux instructions SQL différentes dans une transaction, comme dans l'exemple de LBushkin.

UPDATE : Mon affirmation initiale selon laquelle vous pouviez mettre à jour plusieurs tables dans une vue actualisable était fausse. Sur SQL Server 2005 et 2012, cela génère l'erreur suivante. J'ai corrigé ma réponse pour refléter cela.

Msg 4405, Level 16, State 1, Line 1

View or function 'updatable_view' is not updatable because the modification affects multiple base tables.

1 votes

Alors qu'il n'est pas possible de mettre à jour un objet View qui affectera plusieurs tables, vous pouvez créer AU LIEU DE DÉCLENCHEURS qui décomposent l'original en déclarations distinctes (affectant chacune un tableau) : INSTEAD OF Specifies that the DML trigger is executed instead of the triggering SQL statement, therefore, overriding the actions of the triggering statements. INSTEAD OF cannot be specified for DDL or logon triggers.

9voto

Mick Sharpe Points 1463

Vous devez placer deux instructions de mise à jour à l'intérieur d'une transaction

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X