Hoe twee tabellen in één instructie in SQL Server 2005 bij te werken?

Ik wil twee tabellen in één keer bijwerken. Hoe doe ik dat in 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'

Antwoord 1, autoriteit 100%

U kunt niet meerdere tabellen in één instructie bijwerken, maar u kunt een transactie gebruiken om ervoor te zorgen dat twee update-instructies atomair worden behandeld. Je kunt ze ook batchen om een retourtje te vermijden.

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;

Antwoord 2, autoriteit 45%

Je kunt niet twee tabellen tegelijk updaten, maar je kunt een update koppelen aan een insert met behulp van OUTPUT INTO, en je kunt deze uitvoer gebruiken als een join voor de tweede update:

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;

Ik heb je voorbeeldvoorwaarde voor WHEREgewijzigd in een ander veld dan id. Als het idis en je deze mooie OUTPUTniet nodig hebt, kun je gewoon de tweede tabel updatevoor dezelfde id='010008'.


Antwoord 3, autoriteit 12%

Sorry, afaik, dat kun je niet doen. Om attributen in twee verschillende tabellen bij te werken, moet u twee afzonderlijke instructies uitvoeren. Maar ze kunnen in een batch zitten (een set SQL die in één keer naar de server wordt verzonden)


Antwoord 4, autoriteit 7%

Het korte antwoord daarop is nee. Hoewel u meerdere tabellen kunt invoeren in de from-clausule van een update-instructie, kunt u slechts één tabel opgeven na het trefwoord update. Zelfs als u een “bijwerkbare” weergave schrijft (wat gewoon een weergave is die bepaalde beperkingen volgt), zullen dergelijke updates mislukken. Hier zijn de relevante clips uit de MSDN-documentatie (nadruk ligt van mij).

UPDATE (Transact-SQL)

De weergave waarnaar wordt verwezen door table_or_view_name moet kunnen worden bijgewerkt en verwijzen naar exact één basistabelin de FROM-component van de weergave. Zie CREATE VIEW (Transact-SQL) voor meer informatie over bij te werken weergaven.

WEERGAVE MAKEN (Transact-SQL)

U kunt de gegevens van een onderliggende basistabel wijzigen via een weergave, zolang aan de volgende voorwaarden wordt voldaan:

  • Alle wijzigingen, inclusief UPDATE-, INSERT- en DELETE-instructies, moeten verwijzen naar kolommen uit slechts één basistabel.
  • De kolommen die in de weergave worden gewijzigd, moeten rechtstreeks verwijzen naar de onderliggende gegevens in de tabelkolommen. De kolommen kunnen niet op een andere manier worden afgeleid, bijvoorbeeld via:
    • Een aggregatiefunctie: AVG, COUNT, SUM, MIN, MAX, GROUPING, STDEV, STDEVP, VAR en VARP.
    • Een berekening. De kolom kan niet worden berekend op basis van een expressie die andere kolommen gebruikt. Kolommen die zijn gevormd met behulp van de set-operators UNION, UNION ALL, CROSSJOIN, EXCEPT en INTERSECT vormen een berekening en kunnen ook niet worden bijgewerkt.
  • De kolommen die worden gewijzigd, worden niet beïnvloed door de clausules GROUP BY, HAVING of DISTINCT.
  • TOP wordt nergens gebruikt in de select_statement van de view samen met de WITH CHECK OPTION-component.

Eerlijk gezegd zou u echter moeten overwegen om twee verschillende SQL-instructies binnen een transactie te gebruiken, zoals in het voorbeeld van LBushkin.

UPDATE:Mijn oorspronkelijke bewering dat je meerdere tabellen in een updatebare weergave kon bijwerken, was onjuist. Op SQL Server 2005 & 2012, zal het de volgende fout genereren. Ik heb mijn antwoord gecorrigeerd om dit weer te geven.

Msg 4405, Level 16, State 1, Line 1

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


Antwoord 5, autoriteit 6%

Dit werkt voor MySQL en is eigenlijk gewoon een impliciete transactie, maar het zou ongeveer als volgt moeten gaan:

UPDATE Table1 t1, Table2 t2 SET 
t2.field = t2.field+2,
t1.field = t1.field+2
WHERE t1.id = t2.foreign_id and t2.id = '123414'

als u updates uitvoert voor meerdere tabellen die meerdere verklaringen vereisen… wat waarschijnlijk mogelijk is als u er een bijwerkt, dan een andere op basis van andere voorwaarden… moet u een transactie gebruiken. 


Antwoord 6, autoriteit 5%

U moet twee update-overzichten in een transactie plaatsen


Antwoord 7

U kunt update schrijven voor één tafel en vervolgens een trigger op eerste tafel update, welke update tweede tafel


Antwoord 8

Vanuit mijn perspectief kunt u dit doen, het is één tot één update van twee tabellen in SQL Server:

BEGIN TRANSACTION
      DECLARE @CNSREQ VARCHAR(30)
      DECLARE @ID INT
      DECLARE @CNSRQDT VARCHAR(30)
      DECLARE @ID2 INT
      DECLARE @IDCNSREQ INT
      DECLARE @FINALCNSREQ VARCHAR(30)
      DECLARE @FINALCNSRQDT VARCHAR(30)
      DECLARE @IDCNSRQDT INT
      SET @CNSREQ=(SELECT MIN(REQUISICIONESDT.CNSREQ) FROM REQUISICIONESDT
          INNER JOIN 
              REQUISICIONES
                ON REQUISICIONESDT.CNSRQDT = REQUISICIONES.CNSRQDT AND REQUISICIONES.IDRQDT = REQUISICIONESDT.ID
           AND REQUISICIONES.CNSREQ = REQUISICIONESDT.CNSREQ AND REQUISICIONESDT.IDREQ = REQUISICIONES.ID
        WHERE REQUISICIONES.CNSRQDT = REQUISICIONES.CNSRQDT AND REQUISICIONES.IDRQDT = REQUISICIONESDT.ID)
      SELECT REQUISICIONES.CNSREQ, REQUISICIONES.ID, REQUISICIONES.CNSRQDT FROM REQUISICIONES
       INNER JOIN 
          REQUISICIONESDT
              ON REQUISICIONESDT.CNSRQDT = REQUISICIONES.CNSRQDT AND REQUISICIONES.IDRQDT = REQUISICIONESDT.ID
               AND REQUISICIONES.CNSREQ = REQUISICIONESDT.CNSREQ AND REQUISICIONESDT.IDREQ = REQUISICIONES.ID
        WHERE REQUISICIONES.CNSRQDT = REQUISICIONES.CNSRQDT AND REQUISICIONES.IDRQDT = REQUISICIONESDT.ID
    AND REQUISICIONES.CNSREQ = @CNSREQ
        UPDATE REQUISICIONESDT SET  REQUISICIONESDT.CNSREQ=NULL, REQUISICIONESDT.IDREQ=NULL
          FROM REQUISICIONES INNER JOIN REQUISICIONESDT
             ON REQUISICIONESDT.CNSRQDT = REQUISICIONES.CNSRQDT AND REQUISICIONES.IDRQDT = REQUISICIONESDT.ID
       WHERE REQUISICIONES.CNSRQDT = REQUISICIONES.CNSRQDT AND REQUISICIONES.IDRQDT = REQUISICIONESDT.ID
      AND REQUISICIONES.CNSREQ = @CNSREQ
        UPDATE REQUISICIONES SET REQUISICIONES.CNSRQDT=NULL, REQUISICIONES.IDRQDT=NULL
          FROM REQUISICIONES INNER JOIN REQUISICIONESDT
          ON REQUISICIONESDT.CNSRQDT = REQUISICIONES.CNSRQDT AND REQUISICIONES.IDRQDT = REQUISICIONESDT.ID
       WHERE REQUISICIONES.CNSRQDT = REQUISICIONES.CNSRQDT AND REQUISICIONES.IDRQDT = REQUISICIONESDT.ID
     AND REQUISICIONES.CNSREQ = @CNSREQ
       SET @ID2=(SELECT MIN(REQUISICIONESDT.ID) FROM REQUISICIONESDT
        WHERE ISNULL(REQUISICIONESDT.IDREQ,0)<>0)
     DELETE FROM REQUISICIONESDT WHERE REQUISICIONESDT.ID=@ID2
      SET @IDCNSREQ=(SELECT MIN (REQUISICIONES.ID)FROM REQUISICIONES
          INNER JOIN REQUISICIONESDT ON
        REQUISICIONESDT.CEDULA = REQUISICIONES.CEDULA AND REQUISICIONES.FECHA_SOLICITUD = REQUISICIONESDT.FECHA_SOLICITUD
         WHERE REQUISICIONES.CNSRQDT IS NULL AND REQUISICIONES.IDRQDT IS NULL)
        SET @FINALCNSREQ=(SELECT MIN (REQUISICIONES.CNSREQ)FROM REQUISICIONES
            INNER JOIN REQUISICIONESDT ON
        REQUISICIONESDT.CEDULA = REQUISICIONES.CEDULA AND REQUISICIONES.FECHA_SOLICITUD = REQUISICIONESDT.FECHA_SOLICITUD
         WHERE REQUISICIONES.CNSRQDT IS NULL AND REQUISICIONES.IDRQDT IS NULL)
         SET @FINALCNSRQDT=(SELECT MIN(REQUISICIONESDT.CNSRQDT) FROM REQUISICIONES
           INNER JOIN REQUISICIONESDT ON
          REQUISICIONESDT.CEDULA = REQUISICIONES.CEDULA AND REQUISICIONES.FECHA_SOLICITUD = REQUISICIONESDT.FECHA_SOLICITUD
           WHERE REQUISICIONES.CNSRQDT IS NULL AND REQUISICIONES.IDRQDT IS NULL)
          SET @IDCNSRQDT=(SELECT MIN (REQUISICIONESDT.ID)FROM REQUISICIONES
           INNER JOIN REQUISICIONESDT ON
         REQUISICIONESDT.CEDULA = REQUISICIONES.CEDULA AND REQUISICIONES.FECHA_SOLICITUD = REQUISICIONESDT.FECHA_SOLICITUD  
         WHERE REQUISICIONES.CNSRQDT IS NULL AND REQUISICIONES.IDRQDT IS NULL)
           UPDATE REQUISICIONES SET REQUISICIONES.CNSRQDT = @FINALCNSRQDT, REQUISICIONES.IDRQDT=@IDCNSRQDT FROM REQUISICIONES
            INNER JOIN REQUISICIONESDT ON
             REQUISICIONESDT.CEDULA = REQUISICIONES.CEDULA AND REQUISICIONES.FECHA_SOLICITUD = REQUISICIONESDT.FECHA_SOLICITUD
            WHERE REQUISICIONESDT.CNSRQDT = @FINALCNSRQDT AND REQUISICIONESDT.ID = @IDCNSRQDT 
ROLLBACK TRANSACTION

Antwoord 9

Voor het algemeen bijwerken van tabel1-specifieke kolom op basis van tabel2-specifieke kolom, werkt deze query perfect:

UPDATE table 1  
SET Col 2 = t2.Col2,  
    Col 3 = t2.Col3  
FROM table1 t1  
INNER JOIN table 2 t2 ON t1.Col1 = t2.col1 

Antwoord 10

Het is net zo eenvoudig als deze hieronder getoonde vraag.

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

Other episodes