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'
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'
回答:
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つのテーブルを一度に更新することはできませんが、を使用して更新を挿入にリンクする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'
。
T1.field
はずTable1.field
ですか?
申し訳ありません、ファイフ、それはできません。2つの異なるテーブルの属性を更新するには、2つの個別のステートメントを実行する必要があります。しかし、それらはバッチであることができます(1回の往復でサーバーに送信される一連のSQL)
それに対する簡単な答えはノーです。from
updateステートメントの句には複数のテーブルを入力できますが、update
キーワードの後に指定できるのは1つのテーブルのみです。「更新可能な」ビュー(特定の制限に従う単なるビュー)を作成しても、このような更新は失敗します。これは、MSDNドキュメントの関連クリップです(強調は私のものです)。
table_or_view_nameによって参照されるビューは更新可能で、ビューのFROM句で1つのベーステーブルを正確に参照する必要があります。更新可能なビューの詳細については、「CREATE VIEW(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.
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.
これは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つのテーブルの更新ステートメントを記述してから、2番目のテーブルを更新する最初のテーブル更新のトリガーを作成できます。
私の観点からは、これを行うことができます。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