我想一口气更新两个表。我如何在 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'
您不能在一个语句中更新多个表,但是,您可以使用事务来确保以原子方式处理两个 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;
您不能同时更新两个表,但可以使用 OUTPUT INTO
将更新链接到插入,并且可以将此输出用作第二次更新的连接:
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
为同一个 id='010008'
的第二个表。
T1.field
应该是 Table1.field
吗?
对不起,afaik,你不能那样做。要更新两个不同表中的属性,您需要执行两个单独的语句。但它们可以是成批的(一组 SQL 一次往返发送到服务器)
对此的简短回答是否定的。虽然您可以在更新语句的 from
子句中输入多个表,但您只能在 update
关键字之后指定一个表。即使您确实编写了一个“可更新”视图(它只是一个遵循某些限制的视图),这样的更新也会失败。以下是 MSDN 文档中的相关剪辑(重点是我的)。
table_or_view_name 引用的视图必须是可更新的,并且在视图的 FROM 子句中只引用一个基表。有关可更新视图的详细信息,请参阅 CREATE VIEW (Transact-SQL)。
只要满足以下条件,您就可以通过视图修改基础基表的数据: 任何修改,包括 UPDATE、INSERT 和 DELETE 语句,都必须仅引用一个基表中的列。视图中被修改的列必须直接引用表列中的基础数据。列不能以任何其他方式派生,例如通过以下方式: 聚合函数: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 的示例在事务中使用两个不同的 SQL 语句。
更新:我最初断言您可以在可更新视图中更新多个表是错误的。在 SQL Server 2005 & 2012 上,它会产生以下错误。我已经更正了我的答案以反映这一点。
消息 4405,级别 16,状态 1,第 1 行视图或函数“updatable_view”不可更新,因为修改会影响多个基表。
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'
如果您正在对需要多条语句的多个表进行更新……如果您更新一个,然后根据其他条件更新另一个……您应该使用事务。
您应该在事务中放置两个更新语句
您可以为一个表编写更新语句,然后在第一个表更新时触发一个触发器,它会更新第二个表
从我的角度来看,您可以这样做,它对 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
对于基于 Table2 特定列的一般更新 table1 特定列,此查询完美运行:
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
就像下面显示的这个查询一样简单。
UPDATE
Table1 T1 join Table2 T2 on T1.id = T2.id
SET
T1.LastName='DR. XXXXXX',
T2.WAprrs='start,stop'
WHERE
T1.id = '010008'