6
votes

Mettre à jour la requête sur la table MySQL liée de SQL Server

J'ai un serveur MS SQL avec un serveur MySQL lié. J'ai besoin de synchroniser partiellement une table entre les deux serveurs. Cela se fait en trois étapes et basé sur une condition:

  1. Supprimer toutes les lignes de la table mysql qui ne satisfait pas la condition

  2. Insérez toutes les nouvelles lignes de la table MySQL qui répondent à la condition

  3. Mettez à jour toutes les lignes du serveur MySQL qui répondent à la condition et ont des données différentes entre MySQL et SQL Server

    Les étapes 1 et 2 fonctionnent toujours sans problème. Mais l'étape 3 ne fonctionnera pas s'il y a quelque chose à mettre à jour. La requête échoue avec l'exception suivante: la rowset utilisait une concurrence optimiste et la valeur d'une colonne a été modifiée après que la rangée contenant était extraite ou resynchronisée.].

    est la requête qui est exécutée: xxx

    personne a une idée de la façon d'empêcher cela?


1 commentaires

Désolé pour la fin de la fin de cette question. J'ai utilisé la solution proposée par EmTuCifor et cela a fonctionné. Merci à tous!


7 Réponses :


0
votes

Vous pouvez essayer de créer une deuxième table dans MySQL, effectuer un insertion de SQL-Server dans cette table vide pour toutes les lignes modifiées et faire l'étape 3 entre les deux tables MySQL.


0 commentaires

0
votes

Essayez d'utiliser la sous-requête dans votre relevé où l'instruction. Sous-requête peut retourner plus d'une ligne, puis vous avez eu l'erreur.


1 commentaires

Il utilise l'opérateur dans . Il veut plusieurs rangées. Bien que je pense que le diable est dans les détails et que l'utilisation de la sous-requête est en effet le problème.



0
votes

Essayez de créer une vue qui a une source, une destination et une colonne blanged entre et contient des tables liées jointes. Ensuite, vous pouvez émettre une requête

Mise à jour VI_UPD_LINKEDTABLE SET DESTINATION = SOURCE Où a_changé = 1


0 commentaires

0
votes

Ceci est un tir dans l'obscurité, mais essayez d'ajouter pour mettre à jour ou verrouillage en mode partage à la fin de votre requête de sous-sélection. Cela indiquera à MySQL que vous essayez de sélectionner des objets pour une mise à jour dans votre transaction et de créer un verrouillage d'écriture de niveau de ligne lors de la sélection plutôt que pendant la mise à jour .

de 13.2.8.3. Sélectionnez ... Pour mettre à jour et sélectionner ... Verrouiller en mode Share Verrouillage Reads :

Sélectionnez ... Serrure en mode de partage Définit un Verrouillage de mode partagé sur les lignes lues. UNE Le verrouillage de mode partagé permet à d'autres sessions pour lire les rangées mais pas pour modifier-les. Les rangées lues sont la Dernière disponible, donc s'ils appartiennent à une autre transaction qui n'a pas encore engagé, les blocs de lecture jusqu'à ce que la transaction se termine.


0 commentaires

0
votes

Pour les lignes où les noms sont les mêmes, la mise à jour est un non-op.

Vous n'étilisez aucun travail en essayant de filtrer les rangées où ils sont identiques, car les données doivent encore être comparées sur le lien. Donc je ne peux voir aucun avantage à la sous-requête.

Par conséquent, la requête peut être simplifiée beaucoup: xxx

Éliminer la sous-requête pourrait faire valoir la sous-requête. Le problème de verrouillage disparaît. MySQL a des problèmes combinant un SELECT et un Mettre à jour sur la même table dans une requête donnée.


0 commentaires

2
votes

Essayez cette requête à la place:

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
   )


0 commentaires

0
votes

Essayez ceci. J'ai écrit plusieurs d'entre eux aujourd'hui.

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 (
      ISNULL(b.firstname,'') COLLATE Latin1_General_CI_AI <> ISNULL(k.Voornaam,'')
      or ISNULL(b.middlename,'') COLLATE Latin1_General_CI_AI <> ISNULL(k.Tussenvoegsel,'')
      or ISNULL(b.surname,'') COLLATE Latin1_General_CI_AI <> ISNULL(k.Achternaam,'')
      or ISNULL(b.email,'') COLLATE Latin1_General_CI_AI <> ISNULL(k.e-mail,'')
   )


0 commentaires