SQL Server 2005の1つのステートメントで2つのテーブルを更新する方法


193

2つのテーブルを一度に更新したい。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
理由を説明すると役立ちます。
Eric Mickelsen、2010年

2
申し訳ありませんが、SQL Server 2005では、1つのクエリで複数のテーブルを更新できません。
Pranav Singh 2013

回答:


194

1つのステートメントで複数のテーブルを更新することはできませんが、トランザクションを使用して、2つのUPDATEステートメントがアトミックに処理されるようにすることができます。また、それらをバッチ処理して、往復を回避することもできます。

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;

実際、私はこれら2つのテーブルのレコードを別のテーブルから更新しています。temptableにはtable1へのリンクがありますが、table2へのリンクはありません。Table2の同じレコードを更新するにはどうすればよいですか?どのようにリンクしますか?
ジャンゴ

@unknown:コメントに基づいて、更新クエリが3番目のテーブルのキーを必要とする場合、Table2を更新するときにTable1とTable2の両方を結合する必要があります。それにもかかわらず、2つの個別の更新を実行する必要があります。
LBushkin 2010年

3
おそらく関連していません:mysqlの更新構文が異なるため、これはMYSQLでは機能しません。あなたはUPDATE Table1、Table2 SET Table1.LastName = 'DR。XXXXXX 'WHERE T1.id = T2.id
Juan Vilar

それらの間の主キーと外部キーの関係を維持する必要があるか
srinivas gowda 2017年

2
エラーが発生した場合の部分的な更新を回避するために、try / catchブロック内に更新ステートメントを配置する必要もあります。:この質問を参照stackoverflow.com/questions/1749719/...
mechatroner

84

2つのテーブルを一度に更新することはできませんが、を使用して更新を挿入にリンクするOUTPUT INTOことができ、この出力を2番目の更新の結合として使用できます。

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;

例のWHERE条件を以外のフィールドに変更しましたid。もしそれidがあなたがこの空想を必要としないならOUTPUT、あなたは同じUPDATEためにちょうど2番目のテーブルをすることができますid='010008'


これは最良の回答であり、元の質問に対する真の回答として投票する必要があります。ありがとうございました。それは私のために働いた。
Fandango68 2014年

1
それはあるT1.fieldはずTable1.fieldですか?
WAF

22

申し訳ありません、ファイフ、それはできません。2つの異なるテーブルの属性を更新するには、2つの個別のステートメントを実行する必要があります。しかし、それらはバッチであることができます(1回の往復でサーバーに送信される一連のSQL)


2
やった!私は余分な称賛のためにもっと頻繁に「申し訳ありません」という言葉を使うべきです:P
Fandango68

14

それに対する簡単な答えはノーです。fromupdateステートメントの句には複数のテーブルを入力できますが、updateキーワードの後に指定できるのは1つのテーブルのみです。「更新可能な」ビュー(特定の制限に従う単なるビュー)を作成しても、このような更新は失敗します。これは、MSDNドキュメントの関連クリップです(強調は私のものです)。

UPDATE(Transact-SQL)

table_or_view_nameによって参照されるビューは更新可能で、ビューのFROM句で1つのベーステーブル正確に参照する必要があります。更新可能なビューの詳細については、「CREATE VIEW(Transact-SQL)」を参照してください。

ビューの作成(Transact-SQL)

以下の条件が満たされている限り、ビューを介して基本となる基本テーブルのデータを変更できます。

  • UPDATE、INSERT、DELETEステートメントを含むすべての変更は、1つのベーステーブルののみを参照する必要があります
  • ビューで変更される列は、テーブル列の基になるデータを直接参照する必要があります。列は、次のような他の方法で導出することはできません。
    • 集約関数:AVG、COUNT、SUM、MIN、MAX、GROUPING、STDEV、STDEVP、VAR、VARP。
    • 計算。他の列を使用する式から列を計算することはできません。セット演算子UNION、UNION ALL、CROSSJOIN、EXCEPT、およびINTERSECTを使用して形成された列は、計算に相当し、更新もできません。
  • 変更される列は、GROUP BY、HAVING、またはDISTINCT句の影響を受けません。
  • TOPは、WITH CHECK OPTION句と一緒にビューのselect_statementのどこでも使用されません。

ただし、正直なところ、LBushkinの例のように、トランザクション内で2つの異なるSQLステートメントを使用することを検討する必要があります。

更新:更新可能なビューで複数のテーブルを更新できるという私の元の主張は間違っていました。SQL Server 2005および2012では、次のエラーが生成されます。私はこれを反映するように私の答えを修正しました。

Msg 4405, Level 16, State 1, Line 1

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


1
それは複数のテーブルに影響するViewオブジェクトを更新することはできませんが、あなたが作成することができINSTEAD OFトリガー:(1台ごとに影響を与える)別の文にオリジナルを破る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.
4AM

9

これはMySQLで機能し、実際には単なる暗黙的なトランザクションですが、次のようになります。

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'

複数のステートメントを必要とする複数のテーブルの更新を行っている場合…他の条件に基づいて1つを更新すると、おそらく別の更新が可能になる...トランザクションを使用する必要があります。 


1
このanserは、まだ他のユーザーに関連しています。
Kyselejsyreček

1
@Kyselejsyrečekこの回答は絶対に避けてください。MySQLには十分な癖とにおいがあり、それらのほとんどは実際にはサポートされていませんが、それらの癖に依存するコードを壊さないように保持されています。アップグレードすると、簡単に破損したり、予期しない動作やパフォーマンスの問題が発生したりする可能性があります
Panagiotis Kanavos

7

トランザクション内に2つの更新ステートメントを配置する必要があります


2

1つのテーブルの更新ステートメントを記述してから、2番目のテーブルを更新する最初のテーブル更新のトリガーを作成できます。


0

私の観点からは、これを行うことができます。SQLSERVERの2つのテーブルの1対1の更新です。

 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

以下に示すこのクエリと同じくらい簡単です。

UPDATE 
  Table1 T1 join Table2 T2 on T1.id = T2.id
SET 
  T1.LastName='DR. XXXXXX', 
  T2.WAprrs='start,stop'
WHERE 
  T1.id = '010008'
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.