Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Transmission données SQL Server 2000 vers MySQL (Linux)

7 réponses
Avatar
berthome
Bonjour,

Voici mon problème.

J ai un serveur SQL Server 2000.
Je souhaite insérer dans une table d'une base hébergée sous Mysql par un
serveur Linux.

J ai donc créé un serveur lié pour la base MySQL.

Un insert par :
INSERT OPENQUERY (MySQL, 'SELECT id FROM maBDD.maTABLE')
VALUES('test');
marche bien.





Je souhaite que cet insert dans la base distante se fasse dans un
trigger d update sur une de mes tables.


create trigger TiggerTest on maTABLE
AFTER INSERT
AS
INSERT OPENQUERY (MySQL, 'SELECT id FROM maBDD.maTABLE') VALUES('test');


Le message suivant s'affiche :
Msg 7390, Niveau 16, État 2, Procédure reminder2, Ligne 7
L'opération demandée n'a pas pu être effectuée, car le fournisseur OLE
DB "MSDASQL" du serveur lié 'MySQL' ne prend pas en charge l'interface
de transaction requise.


De meme le script

BEGIN TRAN T1
INSERT OPENQUERY (MySQL, 'SELECT id FROM maBDD.maTABLE')
VALUES('test');
COMMIT TRAN T1;
END_TRAN

provoque la même erreur.

Je soupconne le trigger de créer une transaction.
Ceci peut venir du composant DTC (Distributed Transaction Coordinator)
mais ceci n existe pas sous Linux, à ma connaissance.



Quelqu un sait il résoudre ce problème?

7 réponses

Avatar
berthome
Désolé le client de messagerie me disait que le message n avait pas été
envoyé.

La question est toujours posée?
Avatar
EmanuelL
Bonjour berthome,

Est-ce que arives-tu à te conncter sur le serveur Linux depuis ton
poste Windows?

Arrives-tu à te connecter depuis SQLServer 2000 sur la BD MySQL?
Sinon, voir ici : http://www.connectionstrings.com/mysql.
;-)


berthome a formulé la demande :
Bonjour,

Voici mon problème.

J ai un serveur SQL Server 2000.
Je souhaite insérer dans une table d'une base hébergée sous Mysql par un
serveur Linux.

J ai donc créé un serveur lié pour la base MySQL.

Un insert par :
INSERT OPENQUERY (MySQL, 'SELECT id FROM maBDD.maTABLE') VALUES('test');
marche bien.





Je souhaite que cet insert dans la base distante se fasse dans un trigger d
update sur une de mes tables.


create trigger TiggerTest on maTABLE
AFTER INSERT
AS
INSERT OPENQUERY (MySQL, 'SELECT id FROM maBDD.maTABLE') VALUES('test');


Le message suivant s'affiche :
Msg 7390, Niveau 16, État 2, Procédure reminder2, Ligne 7
L'opération demandée n'a pas pu être effectuée, car le fournisseur OLE DB
"MSDASQL" du serveur lié 'MySQL' ne prend pas en charge l'interface de
transaction requise.


De meme le script

BEGIN TRAN T1
INSERT OPENQUERY (MySQL, 'SELECT id FROM maBDD.maTABLE') VALUES('test');
COMMIT TRAN T1;
END_TRAN

provoque la même erreur.

Je soupconne le trigger de créer une transaction.
Ceci peut venir du composant DTC (Distributed Transaction Coordinator) mais
ceci n existe pas sous Linux, à ma connaissance.



Quelqu un sait il résoudre ce problème?



--

*!* -----------------------------------
EmanuelL
Membre d'AtoutFox
www.atoutfox.org
Avatar
berthome
Est-ce que arives-tu à te conncter sur le serveur Linux depuis ton poste
Windows?

Je n y ai pas accès. Cette machine ne m'appartient pas.


Arrives-tu à te connecter depuis SQLServer 2000 sur la BD MySQL?
Oui, puisque la requete distribuée INSERT OPENQUERY (MySQL, 'SELECT id
FROM maBDD.maTABLE') VALUES('test'); fait bien l insert dans la base
distance.


En fait lorsque j insert INSERT OPENQUERY (MySQL, 'SELECT id FROM
maBDD.maTABLE') VALUES('test'); dans un trigger
J ai le message :

Erreur] Lignes de script: 1-2 ---------------------
L'opération demandée n'a pas pu être effectuée, car le fournisseur OLE
DB "MSDASQL" du serveur lié 'MySQL' ne prend pas en charge l'interface
de transaction requise.
Msg: 7390, Niveau: 16, État: 2, Procédure: reminder2, Ligne: 10 

reminder2 est le nom de mon trigger

Fabien









EmanuelL a écrit :
Bonjour berthome,

Est-ce que arives-tu à te conncter sur le serveur Linux depuis ton poste
Windows?

Arrives-tu à te connecter depuis SQLServer 2000 sur la BD MySQL?
Sinon, voir ici : http://www.connectionstrings.com/mysql.
;-)


berthome a formulé la demande :
Bonjour,

Voici mon problème.

J ai un serveur SQL Server 2000.
Je souhaite insérer dans une table d'une base hébergée sous Mysql par
un serveur Linux.

J ai donc créé un serveur lié pour la base MySQL.

Un insert par :
INSERT OPENQUERY (MySQL, 'SELECT id FROM maBDD.maTABLE')
VALUES('test');
marche bien.





Je souhaite que cet insert dans la base distante se fasse dans un
trigger d update sur une de mes tables.


create trigger TiggerTest on maTABLE
AFTER INSERT
AS
INSERT OPENQUERY (MySQL, 'SELECT id FROM maBDD.maTABLE')
VALUES('test');


Le message suivant s'affiche :
Msg 7390, Niveau 16, État 2, Procédure reminder2, Ligne 7
L'opération demandée n'a pas pu être effectuée, car le fournisseur OLE
DB "MSDASQL" du serveur lié 'MySQL' ne prend pas en charge l'interface
de transaction requise.


De meme le script

BEGIN TRAN T1
INSERT OPENQUERY (MySQL, 'SELECT id FROM maBDD.maTABLE')
VALUES('test');
COMMIT TRAN T1;
END_TRAN

provoque la même erreur.

Je soupconne le trigger de créer une transaction.
Ceci peut venir du composant DTC (Distributed Transaction Coordinator)
mais ceci n existe pas sous Linux, à ma connaissance.



Quelqu un sait il résoudre ce problème?





Avatar
Patrice
Je pense qu'un forum MySQL serait plus approprié.

Pour l'instant, il semble bien que le problème soit que le pilote utilisé
pour accéder à MySQL ne supporte pas les transactions distribuées (ce qui me
semble nécessaire pour qu'une erreur dans le trigger annule bien la
modification qui est à l'origine de son déclenchement). A priori, c'est
plutôt un problème MySQL...

Vori peut-être du côté de http://dev.mysql.com/doc/refman/5.0/en/xa.html (je
ne connais pas MySQL).

Sinon, il faudrait alores changer de stratégie. Par exemple si les liens
sont peu fréquents, passer par une procédure stockée ce qui permettrait
d'obtenir le résultat voulu (mais en perdant l'intégrité entre les deux
serveurs si la mise à jour MySQL plante, il est éventuellement possible de
prévoir une "réconciliation" par la suite).

--
Patrice
Avatar
berthome
J ai reecris ma procedure :

CREATE TRIGGER [dbo].[reminder2]
ON [dbo].[tbFBE]
AFTER INSERT
AS
BEGIN
DECLARE @id int;

SELECT @id = id from inserted
END
COMMIT TRANSACTION;
print 'valeur ajouter ' + cast(@id as varchar);

EXEC proc_fbe @id
GO

avec

CREATE PROCEDURE [dbo].[proc_fbe]
@id int
AS
INSERT OPENQUERY (BASE_DISTANTE, 'SELECT id FROM dotmobil.dotbox')
VALUES (@id);


Je souhaite en effet que le trigger ne soit pas transactionnel;
l'insert de la procedure stockée ne doit pas affecter l insert du
trigger. Si l insert de la procédure stockée plante, la ligne inseree
sur le serveur local doit pas etre rollbacker.

Est ce la bonne manière de faire?



Lorsque je fait insert into tbFBE values (358);

J ai un message valeur ajouter 358

(1 ligne(s) affectée(s))
Msg 3609, Niveau 16, État 1, Ligne 1
La transaction s'est terminée dans le déclencheur. Le lot a été abandonné.

Les lignes sont bien inserees en local et sur la base distante.

ceci vient du commit. Comment resoudre cela?
Si je ne mets pas le commit:
Msg 7390, Niveau 16, État 2, Procédure proc_fbe, Ligne 9
L'opération demandée n'a pas pu être effectuée, car le fournisseur OLE
DB "MSDASQL" du serveur lié 'BASE_DISTANTE' ne prend pas en charge
l'interface de transaction requise.










Patrice a écrit :
Je pense qu'un forum MySQL serait plus approprié.

Pour l'instant, il semble bien que le problème soit que le pilote utilisé
pour accéder à MySQL ne supporte pas les transactions distribuées (ce qui me
semble nécessaire pour qu'une erreur dans le trigger annule bien la
modification qui est à l'origine de son déclenchement). A priori, c'est
plutôt un problème MySQL...

Vori peut-être du côté de http://dev.mysql.com/doc/refman/5.0/en/xa.html (je
ne connais pas MySQL).

Sinon, il faudrait alores changer de stratégie. Par exemple si les liens
sont peu fréquents, passer par une procédure stockée ce qui permettrait
d'obtenir le résultat voulu (mais en perdant l'intégrité entre les deux
serveurs si la mise à jour MySQL plante, il est éventuellement possible de
prévoir une "réconciliation" par la suite).

--
Patrice








Avatar
bruno reiter
un TRIGGER se déclanche obligatoirement dans la même transaction.
Il faut que les MàJ de la table MSSQL et de celle MySQL se fassent dans une
PROC qui fera les 2 INSERT sans transaction distribuée.

BR

"berthome" wrote in message
news:
J ai reecris ma procedure :

CREATE TRIGGER [dbo].[reminder2]
ON [dbo].[tbFBE]
AFTER INSERT
AS
BEGIN
DECLARE @id int;

SELECT @id = id from inserted
END
COMMIT TRANSACTION;
print 'valeur ajouter ' + cast(@id as varchar);

EXEC proc_fbe @id
GO

avec

CREATE PROCEDURE [dbo].[proc_fbe]
@id int
AS
INSERT OPENQUERY (BASE_DISTANTE, 'SELECT id FROM dotmobil.dotbox') VALUES
(@id);


Je souhaite en effet que le trigger ne soit pas transactionnel;
l'insert de la procedure stockée ne doit pas affecter l insert du trigger.
Si l insert de la procédure stockée plante, la ligne inseree sur le
serveur local doit pas etre rollbacker.

Est ce la bonne manière de faire?



Lorsque je fait insert into tbFBE values (358);

J ai un message valeur ajouter 358

(1 ligne(s) affectée(s))
Msg 3609, Niveau 16, État 1, Ligne 1
La transaction s'est terminée dans le déclencheur. Le lot a été abandonné.

Les lignes sont bien inserees en local et sur la base distante.

ceci vient du commit. Comment resoudre cela?
Si je ne mets pas le commit:
Msg 7390, Niveau 16, État 2, Procédure proc_fbe, Ligne 9
L'opération demandée n'a pas pu être effectuée, car le fournisseur OLE DB
"MSDASQL" du serveur lié 'BASE_DISTANTE' ne prend pas en charge
l'interface de transaction requise.










Patrice a écrit :
Je pense qu'un forum MySQL serait plus approprié.

Pour l'instant, il semble bien que le problème soit que le pilote utilisé
pour accéder à MySQL ne supporte pas les transactions distribuées (ce qui
me semble nécessaire pour qu'une erreur dans le trigger annule bien la
modification qui est à l'origine de son déclenchement). A priori, c'est
plutôt un problème MySQL...

Vori peut-être du côté de http://dev.mysql.com/doc/refman/5.0/en/xa.html
(je ne connais pas MySQL).

Sinon, il faudrait alores changer de stratégie. Par exemple si les liens
sont peu fréquents, passer par une procédure stockée ce qui permettrait
d'obtenir le résultat voulu (mais en perdant l'intégrité entre les deux
serveurs si la mise à jour MySQL plante, il est éventuellement possible
de prévoir une "réconciliation" par la suite).

--
Patrice








Avatar
Patrice
Cela ne change rien au problème la procédure est toujours appelé dans le
trigger qui, j'imagine, tourne "by design" dans une transaction pour
garantir que si le trigger échoue la modification d'origine sera annulée..

Je voulais dire mettre à jour les données SQL Server via une procédure
stockée unique et sans aucun trigger :

CREATE PROCEDURE [dbo].InsertEveryWhere(@id int) AS
BEGIN
-- Insérer dans SQL Server
INSERT INTO MyTable(MyID) VALUES (@id)
-- Insérer dans MySQL
INSERT OPENQUERY (BASE_DISTANTE, 'SELECT id FROM dotmobil.dotbox') VALUES
(@id)
END

Bien que l'idée de terminer la transaction serait une autre voie (en
masquant l'erreur peut-être avec un try catch et la procédure stockée
n'apporte rien), généralement je n'aime pas trop ce genre de contournements
(après c'est toi qui choisi !!).

La dernière solution que je vois serait de découpler les deux mises à jour
en "postant" les modifications (par exemple vers une file) et d'avoir un
service qui lirait cette file pour envoyer les insertions vers MySQL... Là
on pourrait à nouveau utiliser un trigger...

--
Patrice