首页 > 解决方案 > 如何选择临时表并立即更新

问题描述

我将 MySql 链接到 Sql Server 作为STATION_TEST. 我想将以下选择结果输入临时表并更新。选择查询:

SELECT * INTO #MYSqlRFID_Prod FROM OPENQUERY(STATION_TEST,'select * from deslocal.RFID_Prod WHERE valid = ''N''');

我不能选择两次进行更新,因为表 RFID_Prod 记录每次都在运行。如果我这样查询:

UPDATE OPENQUERY(STATION_TEST,'SELECT id,valid FROM deslocal.RFID_Prod WHERE valid = ''N''') SET valid = 'Y';

恐怕选择结果会与第一次选择不同。

标签: mysqlsqlsql-serveropenquery

解决方案


您可以对链接服务器使用标准的 UPDATE FROM SELECT 语法。

UPDATE 
   LinkedTable
SET 
   LinkedTable.Field1= 123
FROM
   (
        SELECT *  FROM OPENQUERY(STATION_TEST,'select * from deslocal.RFID_Prod WHERE valid = ''N''')   
   ) AS LinkedTable       
WHERE
    LinkedTable.Field2=456

但是,如果您尝试OUTPUT INSERTED进入 @Temp 表,如下所示:

DECLARE @Updated table(Field1 INT,Field2 INT)

WITH X AS(SELECT *  FROM OPENQUERY(STATION_TEST,'select * from deslocal.RFID_Prod WHERE valid = ''N'''))
UPDATE
  T
SET
  T.Field1 = 2212 
OUTPUT 
    INSERTED.Field2,INSERTED.Field2 
    INTO @Updated
FROM
    (SELECT * FROM X )AS T
WHERE 
    T.Field1=123

该语句将失败并显示以下消息。

远程表不能用作包含 OUTPUT 子句或嵌套 DML 语句的语句中的 DML 目标。

使用链接服务器更新和选择似乎需要两个语句。

但是......您可能能够将 OUTPUT INSERTED 的结果通过管道传输到远程表中,但是,它仍然是调用结果集的第二条语句。

还有两个选择

将关键更新关联键添加到目标表。

ALTER deslocal ADD(CriticalCorrelationID UNIQUEIDENTIFIER)
..

DECLARE @CorrelationID UNIQUEIDENTIFIER = NEW_ID()


UPDATE 
    STATION_TEST.YourDatabaseName.dbo.deslocal 
SET 
    Valid='Y',
    CriticalCorrelationID=@CorrelationID 
WHERE
    Valid='N'

SELECT * FROM STATION_TEST.YourDatabaseName.dbo.deslocal 
WHERE CriticalCorrelationID=@CorrelationID 

使用分布式事务

BEGIN DISTRIBUTED TRANS
UPDATE STATION_TEST.YourDatabaseName.dbo.deslocal 
...
SELECT * FROM STATION_TEST.YourDatabaseName.dbo.deslocal WHERE
COMMIT TRANS

推荐阅读