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:
Supprimer toutes les lignes de la table mysql qui ne satisfait pas la condition p> li>
Insérez toutes les nouvelles lignes de la table MySQL qui répondent à la condition p> li>
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 P> LI> ol>
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.]. P> P> est la requête qui est exécutée: p> personne a une idée de la façon d'empêcher cela? p> p>
7 Réponses :
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. P>
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. P>
Il utilise l'opérateur dans code>. 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.
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 p>
Mise à jour VI_UPD_LINKEDTABLE SET DESTINATION = SOURCE Où a_changé = 1 P>
Ceci est un tir dans l'obscurité, mais essayez d'ajouter 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. p>
blockQuote> pour mettre à jour code> ou
verrouillage en mode partage code> à 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 code> plutôt que pendant la mise à jour code>. p>
Pour les lignes où les noms sont les mêmes, la mise à jour 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. P> Par conséquent, la requête peut être simplifiée beaucoup: p> É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 code> est un non-op.
SELECT CODE> et un
Mettre à jour code> sur la même table dans une requête donnée. P> p>
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 )
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,'') )
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!