MySQL Déclenche - APRÈS déclencheur INSERT + UDF sys_exec() question
Problème: j'ai une table qui détient des records. Après l'insertion a été fait, je tiens à appeler un programme externe (script php) via MySQL sys_* Udf.
Maintenant, la question - le déclencheur, j'ai passe l'ID de l'enregistrement du script.
Lorsque j'essaie de tirer les données via le script, j'obtiens 0 lignes.
Au cours de mes propres essais, j'en suis venu à la conclusion que le déclencheur invoque le script php et transmet les paramètres AVANT l'insertion s'est produit, donc je n'ai pas de dossiers pour l'ID donné.
J'ai testé cela sur MySQL 5.0.75 et 5.1.41 (Ubuntu OS).
Je peux confirmer que les paramètres sont passés au script avant même l'insert se produit parce que j'ai ajouté sleep(2); à mon script php et j'ai obtenu les données correctement.
Sans dormir(); déclaration, je reçois 0 enregistrements pour l'ID donné.
Ma question est - comment résoudre ce problème sans avoir à coder en dur une sorte de retard dans le script php?
Je n'ai pas la liberté d'en supposant que 2 secondes ou 10 secondes) sera suffisante retard, donc je veux que tout le flux "naturellement", quand une commande est terminée - l'autre est exécuté.
Je suppose que si le déclencheur est de type AFTER INSERT, le tout dans le corps de l'élément déclencheur sera exécuté après que MySQL fait insère les données.
Disposition de Table:
CREATE TABLE test (
id int not null auto_increment PRIMARY KEY,
random_data varchar(255) not null
);
Déclencher la mise en page:
DELIMITER $$
CREATE TRIGGER `test_after_insert` AFTER INSERT ON `test`
FOR EACH ROW BEGIN
SET @exec_var = sys_exec(CONCAT('php /var/www/xyz/servers/dispatcher.php ', NEW.id));
END;
$$
DELIMITER ;
Avertissement: je sais que les questions de sécurité lors de l'utilisation de sys_exec fonction, mon problème est que MySQL ne pas insérer d'ABORD et ENSUITE appeler le script avec les paramètres nécessaires.
Si quelqu'un peut jeter une certaine lumière sur la façon de résoudre ce problème ou a une approche différente qui n'implique pas de SELECT INTO OUTFILE et à l'aide de la GPA - je lui en serais très reconnaissant. Merci à l'avance.
De données est insérée. Déclencheur est appelé et transmet l'ID de l'dispatcher.php. Dispatcher.php récupère la ligne et l'envoie au navigateur. Raison pour laquelle je ne suis pas de l'envoi de l'ensemble des données sur l'insert est parce que je vais les insérer dans un tableau mais je vais extraire les données à partir de la vue - donc, je ne connais pas toutes les colonnes que je vais utiliser à un moment donné.
Donc, dispatcher.php a son propre client de connexion à mySQL? Ce n'est pas fiable, car l'insertion / mise à jour de transaction dans laquelle votre déclencheur s'exécute n'est pas complète jusqu'à ce que votre déclencheur est fait. Donc, dispatcher.php voit soit incompatible ou pré-données de la transaction. En tout cas, c'est comme manger une tranche de tarte pendant que la tarte est encore dans le four. les déclencheurs doivent rester à l'intérieur de la base de données du serveur.
Soit vous n'avez pas lu ce que j'ai écrit ou ne comprenez pas la question, puisque vous avez posé une question après je l'ai expliqué dans plutôt de manière simple ce qu'il se passe. Je n'ai pas l'intention d'être impoli, mais votre réponse n'est pas de m'aider dans toute sorte de façon.
avez-vous jamais comprendre cela?
OriginalL'auteur Mihael | 2010-09-06
Vous devez vous connecter pour publier un commentaire.
Si je comprends bien, vous insérez une ligne dans votre base de données. Qu'invoquer un déclencheur de lancer une commande externe, écrit en PHP. Cette commande interroge à son tour la même DB à l'aide de la id de la ligne insérée?
Je n'ai pas pense c'est un problème de "retard".
Le vrai "problème" est votre premier insert et vous commande externe se connecter à la même DB sur deux des séances de - probablement dans deux différents les transactions (en fonction de votre moteur de base de données et votre niveau d'isolation de transaction).
Je assumer, lorsque la gâchette invoqué la ligne à insérer n'est pas encore engagé à la DB. Si la commande externe de toujours voir la DB comme il était avant.
BTW, si l'explication ci-dessus est très spéculatif, ce qui est plus évident pour moi, c'est que vous pensez probablement que c'est une conception différente que d'essayer de le fait que le travail tel qu'il est.
OriginalL'auteur Sylvain Leroux
Même si vous utilisez un déclencheur AFTER, la ligne n'est pas encore commis. Mais sys_exec() ne retourne pas jusqu'à ce que le script php sorties, de sorte que le déclencheur AFTER ne peut pas complet, par conséquent vous ne pouvez pas valider l'INSERTION.
C'est par la conception. Après tout, vous pouvez faire plus d'opérations au sein de la même opération, ou vous pouvez annuler la transaction. C'est le problème avec l'invocation d'un processus externe à partir d'un déclencheur: processus externes ne peuvent pas voir les données dans le champ d'application de la transaction dans la base de données.
Vous ne devriez pas faire cette tâche avec un seuil de déclenchement. Au mieux, vous devez utiliser le déclencheur pour définir un "drapeau" de la colonne, puis d'écrire un processus externe à regarder pour les lignes avec le drapeau et ensuite appeler ce script PHP. De cette façon, seulement les lignes qui ont été correctement inséré ET engagés seront traitées.
bien sûr, vous pourriez passer toute la ligne pour le script. Mais que faire si l'INSERT est partie d'une transaction qui n'est finalement annulée? Ensuite, le script a juste agi sur des données qui ne seront jamais visibles dans la base de données.
Merci Bill! Qui fait sens. Je suppose qu'on pourrait appeler une procédure supplémentaire ou quelque chose.
OriginalL'auteur Bill Karwin