SQL Server 2005'te bir tablodaki iki tablo nasıl güncelleştirilir?


193

Tek seferde iki tabloyu güncellemek istiyorum. Bunu SQL Server 2005'te nasıl yapabilirim?

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
Nedenini açıklarsan yardımcı olur.
Eric Mickelsen

2
Korkarım, SQL Server 2005 bir sorguda birden çok tablonun güncellenmesini desteklemez.
Pranav Singh

Yanıtlar:


195

Bir ifadede birden çok tabloyu güncelleyemezsiniz, ancak iki UPDATEifadenin atomik olarak ele alındığından emin olmak için bir işlem kullanabilirsiniz . Ayrıca, gidiş-dönüş seyahatlerinden kaçınmak için bunları toplu olarak kullanabilirsiniz.

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;

Aslında, bu iki tablonun kayıtlarını başka bir şablondan güncelliyorum. temptable'ın table1 bağlantısı vardır, ancak table2 bağlantısı yoktur. Aynı Table2 kaydını nasıl güncelleyebilirim? Nasıl bağlayacağım?
Jango

@unknown: Yorumunuza dayanarak, güncelleme sorgunuzun üçüncü bir tablodaki anahtarlara ihtiyacı varsa Table2'yi güncellediğinizde hem Table1 hem de Table2'ye katılmanız gerekir. Ne olursa olsun, yine de iki ayrı güncelleme yapmanız gerekiyor.
LBushkin

3
muhtemelen ilgili değil: mysql için güncelleme sözdizimi farklı olduğundan bu MYSQL üzerinde çalışmaz. UPDATE Table1, Table2 SET Table1.LastName = 'DR gitmek gerekir. XXXXXX 'NEREDE T1.id = T2.id
Juan Vilar

arasında birincil anahtar ve yabancı anahtar ilişkisini korumamız gerekiyor mu
srinivas gowda

2
Hata durumunda kısmi güncellemeyi önlemek için güncelleme ifadelerinizi try / catch bloğunun içine koymalısınız. bu soruya bakın: stackoverflow.com/questions/1749719/…
mechatroner

84

Aynı anda iki tabloyu güncelleyemezsiniz, ancak bir güncellemeyi kullanarak bir eke bağlayabilirsiniz OUTPUT INTOve bu çıktıyı ikinci güncelleştirme için birleştirme olarak kullanabilirsiniz:

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;

Örnek WHEREdurumunuzu başka bir alan olarak değiştirdim id. Eğer idbu fantaziye ihtiyacınız OUTPUTyoksa, sadece UPDATEikinci tabloyu aynı şekilde yapabilirsiniz id='010008'.


Bu en iyi cevaptır ve orijinal sorunun gerçek cevabı olarak oylanmalıdır. Teşekkür ederim. Benim için çalıştı.
fandango68

1
Bunun T1.fieldolması gerekiyor Table1.fieldmu?
WAF

22

Üzgünüm, afaik, bunu yapamazsın. Öznitelikleri iki farklı tabloda güncellemek için iki ayrı ifade yürütmeniz gerekir. Ancak bir toplu işte olabilirler (tek seferde sunucuya gönderilen bir SQL kümesi)


2
Allah Allah! Fazladan zevkleri için daha sık Maalesef kelimesini kullanmalıdır: P
fandango68

14

Bunun kısa cevabı hayır. fromBir güncelleme ifadesinin yan tümcesine birden çok tablo girebilirsiniz , ancak updateanahtar kelimeden sonra yalnızca tek bir tablo belirtebilirsiniz . "Güncellenebilir" bir görünüm yazsanız bile (yalnızca belirli kısıtlamalara uyan bir görünümdür), bunun gibi güncellemeler başarısız olur. İşte MSDN belgelerindeki ilgili klipler (vurgu benimdir).

GÜNCELLEME (Transact-sql)

Table_or_view_name tarafından başvurulan görünüm güncelleştirilebilir olmalı ve görünümün FROM yan tümcesinde tam olarak bir temel tabloya başvurmalıdır . Güncellenebilir görünümler hakkında daha fazla bilgi için bkz. GÖRÜNÜM OLUŞTUR (Transact-sql).

GÖRÜNÜMÜ OLUŞTUR (Transact-sql)

Aşağıdaki koşullar geçerli olduğu sürece, temel alınan temel tablonun verilerini bir görünüm aracılığıyla değiştirebilirsiniz:

  • UPDATE, INSERT ve DELETE deyimleri dahil olmak üzere tüm değişiklikler, yalnızca bir temel tablodaki sütunlara başvurmalıdır .
  • Görünümde değiştirilen sütunlar, tablo sütunlarındaki temel verilere doğrudan başvurmalıdır. Sütunlar, aşağıdakiler gibi başka bir şekilde türetilemez:
    • Toplama işlevi: AVG, COUNT, SUM, MIN, MAX, GROUPING, STDEV, STDEVP, VAR ve VARP.
    • Bir hesaplama. Sütun, diğer sütunları kullanan bir ifadeden hesaplanamaz. UNION, UNION ALL, CROSSJOIN, EXCEPT ve INTERSECT ayarlanmış işleçleri kullanılarak oluşturulan sütunlar bir hesaplama anlamına gelir ve ayrıca güncelleştirilemez.
  • Değiştirilen sütunlar GROUP BY, HAVING veya DISTINCT deyimlerinden etkilenmez.
  • TOP, WITH CHECK OPTION yantümcesi ile birlikte görünümün select_statement kısmında hiçbir yerde kullanılmaz.

Her şeye rağmen, LBushkin örneğine göre bir işlem içinde iki farklı SQL ifadesi kullanmayı düşünmelisiniz.

GÜNCELLEME: Güncellenebilir bir görünümde birden çok tabloyu güncelleyebileceğinize ilişkin orijinal iddiam yanlıştı. SQL Server 2005 ve 2012'de aşağıdaki hatayı oluşturur. Bunu yansıtmak için cevabımı düzelttim.

Msg 4405, Level 16, State 1, Line 1

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


1
Birden çok tabloyu etkileyecek bir View nesnesini güncellemek mümkün olmasa da , orijinali ayrı ifadelere bölen INSTEAD OF tetikleyicileri oluşturabilirsiniz (her biri bir tabloyu etkiler):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.
04:00

9

Bu MySQL için çalışır ve gerçekten sadece örtük bir işlemdir, ancak böyle bir şey yapmalıdır:

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'

çoklu tablolar gerektiren çoklu tablolar için güncellemeler yapıyorsanız… büyük olasılıkla birini güncellerseniz mümkündür, o zaman başka koşullara dayalı olarak diğerini… bir işlem kullanmalısınız. 


1
Bu yanıt, diğer kullanıcılar için hala geçerlidir.
Kyselejsyreček

1
@ Kyselejsyreček bu cevap ne pahasına olursa olsun kaçınılmalıdır. MySQL, çoğu desteklenmeyen, ancak bu tuhaflıklara bağlı kod kırılmasını önlemek için yeterli tuhaflık ve kokuya sahiptir. Yükseltme onları kolayca kırabilir veya beklenmedik davranış ve performans sorunlarına neden olabilir
Panagiotis Kanavos

7

Bir işlemin içine iki güncelleme ifadesi yerleştirmelisiniz



0

Benim açımdan bunu yapabilirsiniz, SQL SERVER'de iki tablonun bire bir güncellemesi:

 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

-2

Aşağıda gösterilen bu sorgu kadar basittir.

UPDATE 
  Table1 T1 join Table2 T2 on T1.id = T2.id
SET 
  T1.LastName='DR. XXXXXX', 
  T2.WAprrs='start,stop'
WHERE 
  T1.id = '010008'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.