从SQL Server更新链接MySQL表的查询

Bir*_*ger 6 mysql sql-server

我有一个带有链接MySQL服务器的MS SQL Server.我需要在两个服务器之间部分同步一个表.这是基于以下三个步骤完成的:

  1. 删除MySQL表中不满足条件的所有行

  2. 在MySQL表中插入满足条件的所有新行

  3. 更新MySQL服务器中满足条件的所有行,并在MySQL和SQL Server之间具有不同的数据

步骤1和2始终没有问题.但如果有任何更新,第3步将无法运行.查询失败,出现以下异常:行集使用了乐观并发,并且在上次提取或重新同步包含行后,列的值已更改.

这是执行的查询:

update mysqlserver...subscribers
set Firstname = Voornaam, 
  Middlename = Tussenvoegsel, 
  Surname = Achternaam, 
  email = e-mail 
from mysqlserver...subscribers as b, tblkandidaat 
where (b.kandidaatid = tblkandidaat.kandidaatid) and
  (tblkandidaat.kandidaatid in (
    select subsc.kandidaatid
    from mysqlserver...subscribers subsc inner join tblKandidaat 
      on (subsc.kandidaatid=tblKandidaat.kandidaatid) 
    where (subsc.list=1) and
      ((subsc.firstname COLLATE Latin1_General_CI_AI <> Voornaam 
      or (subsc.middlename COLLATE Latin1_General_CI_AI <> Tussenvoegsel) 
      or (subsc.surname COLLATE Latin1_General_CI_AI <> tblKandidaat.Achternaam) 
      or (subsc.email COLLATE Latin1_General_CI_AI <> tblKandidaat.e-mail))
  ));
Run Code Online (Sandbox Code Playgroud)

有人知道如何防止这种情况吗?

Eri*_*ikE 2

请尝试以下查询:

update b
set
   Firstname = Voornaam, 
   Middlename = Tussenvoegsel, 
   Surname = Achternaam, 
   email = e-mail 
from
   mysqlserver...subscribers b
   inner join tblkandidaat k on b.kandidaatid = k.kandidaatid
where
   b.list=1
   and (
      b.firstname COLLATE Latin1_General_CI_AI <> k.Voornaam 
      or b.middlename COLLATE Latin1_General_CI_AI <> k.Tussenvoegsel
      or b.surname COLLATE Latin1_General_CI_AI <> k.Achternaam
      or b.email COLLATE Latin1_General_CI_AI <> k.e-mail
   )
Run Code Online (Sandbox Code Playgroud)
  1. 最佳实践是使用 ANSI 连接并将 JOIN 条件与 WHERE 条件正确分开。

  2. 在整个查询中为所有表使用别名而不是长表名更具可读性。

  3. 最好对所有列引用使用别名,而不是将其留空。这不仅是一个好习惯,可以让事情变得更清晰,而且可以避免内部表与外部表引用中的一些非常讨厌的错误。

  4. 如果性能也是一个问题:链接服务器连接有时会转变成数据库数据提供程序引擎中的逐行处理。我发现一些情况,将链接服务器上的复杂联接的一部分分解为常规联接,然后进行交叉应用,大大减少了提取不需要的行,并大大提高了性能。(这本质上是进行书签查找,也称为非聚集索引扫描,然后使用这些值进行聚集索引查找)。虽然这可能不完全符合 MySql 的工作方式,但值得尝试。如果您可以进行任何类型的跟踪来查看在 MySql 端执行的实际查询,您可能会深入了解用于提高性能的其他方法。

  5. 另一个提高性能的想法是将远程数据本地复制到临时表,并添加 ActionRequired 列。然后更新临时表,使其看起来应该如此,在 ActionRequired 中放入“U”、“I”或“D”,然后使用 ActionRequired 在主键上使用简单的等值连接在链接服务器上执行合并/更新插入。仔细注意可能的竞争条件,在处理过程中远程数据库可能会被更新。

  6. 当心空值...您正在比较的所有列都是不可空的吗?