2017-02-15 3 views
1

Je suis complètement nouveau à MySQL, et je me suis cogné avec quelques erreurs, mais toujours je trouve des solutions, sauf pour celui-ci je ne comprends pas comment le contourner . La procédure MySQL suivante me renvoie une valeur si la variable "ue" est 1 ou 0 (un tas de validation existe). La partie de validation (SET ue = EXISTS ...) fonctionne sans le reste du code, comme il se doit, le problème n'est pas là. Mais quand j'exécute la commande INSERT INTO SELECT, ça ne marche pas, ça renvoie toujours 0 comme réponse, quand ça devrait être 1. Ces deux lignes se mettent en confrontation.La procédure MySQL renvoyant une valeur erronée (INSERT SELECT en confrontation)

INSERT INTO meetup_participation SELECT id_utilisateur, event_id FROM DUAL WHERE ue = 1;

SELECT ue AS réponse;

La procédure devrait ajouter « ID utilisateur » et « ID d'événement » dans meetup_participation, puis mettre à jour la ligne à des « utilisateurs » correspondant à l'utilisateur que « ID utilisateur » pour incrémenter les «événements ont participé. Et il UPDATE également pour incrémenter la participation à l'événement avec cet 'identifiant d'événement'. J'utilise SET ue pour valider des choses comme, si l'utilisateur existe, si l'événement existe, si la date de l'événement est toujours valide et si l'utilisateur ne figure pas déjà dans ce tableau. Donc je passe cette valeur en tant que booléen à INSERT INTO meetup_participation [...] WHERE ue = 1. Après cela, je fais SELECT ue pour informer la validation retournée true et la procédure exécutée sans problèmes.

Voici la procédure complète.

CREATE DEFINER=`user`@`localhost` PROCEDURE `join_event`(IN `user_id` BIGINT(64), IN `event_id` INT) NOT DETERMINISTIC MODIFIES SQL DATA SQL SECURITY DEFINER 

begin 

DECLARE ue INT; 
SET ue = EXISTS(SELECT 1 FROM users WHERE fb_uid=user_id) AND EXISTS(SELECT 1 FROM meetup WHERE meet_id=event_id) AND EXISTS(SELECT 1 FROM meetup WHERE date > NOW() AND meet_id = event_id) AND EXISTS(SELECT 1 FROM meetup WHERE meet_id = event_id AND participants <= max_participants) AND NOT EXISTS(SELECT 1 FROM meetup_participation WHERE fb_uid = user_id AND meet_id = event_id); 

INSERT INTO meetup_participation SELECT user_id, event_id FROM DUAL WHERE ue=1; 

UPDATE users SET events_participated = events_participated + 1 WHERE fb_uid=user_id AND ue=1; 
UPDATE meetup SET participants = participants + 1 WHERE meet_id=event_id AND ue=1; 
SELECT ue AS response; 

end 

Merci d'avance.

+0

Il est difficile de comprendre à partir du segment de code quels champs proviennent des tables de base de données et quels sont les paramètres transmis à la procédure.Cela aiderait si vous pouviez fournir l'instruction create procedure avec les déclarations de variables et alias les noms de colonnes provenant de la base de données. Si la procédure n'est pas trop longue, éditez la question pour inclure la procédure complète. Aussi, je ne sais pas ce que ces deux lignes deviennent en face des moyens, pouvez-vous trouver une autre façon de décrire ce que vous voulez dire? –

+0

@ P.Salmon J'ai édité le code pour une meilleure compréhension, en face je veux dire, sans 'INSERT INTO SELECT', il retourne la bonne valeur qu'il devrait ... Confront pourrait ne pas être la bonne façon de dire en anglais. –

+0

Votre procédure fonctionne - avec les exceptions possibles de SET events_participated = events_payicipated + 1 et SET participants = participants + 1 qui doivent être qualifiés pour répondre à une valeur de départ de null - SET events_participated = ifnull (events_payicipated, 0) + 1 et SET participants = ifnull (participants, 0) + 1. –

Répondre

0

L'instruction INSERT est exécutée séparément de l'instruction SET ue = .... Je ne suis pas sûr de ce que vous essayez d'accomplir, mais le code n'a aucun sens. Si vous souhaitez ajouter des enregistrements à meetup_participation en fonction des tests EXISTS appliqués à chaque enregistrement de la table des utilisateurs, vous devez appliquer les tests à chaque enregistrement de votre instruction SELECT dans le cadre de INSERT.

Il existe également de nombreux problèmes de syntaxe/grammaire dans le code, comme illustré.

Si vous pouviez fournir une explication de ce que vous essayez d'accomplir avec la procédure, cela pourrait permettre à quelqu'un de suggérer la bonne façon de coder la procédure.

+0

Je suis désolé, je ne sais pas pourquoi cela n'a pas de sens ... J'ai édité la question, peut-être que c'est mieux ... Le code ne fonctionne pas (insérer, mettre à jour ...) sauf pour retourner le sélectionné valeur, et le code de sélection fonctionne sans commande INSERT. Quels sont les problèmes de grammaire/syntaxe? PMA ne m'avertit pas de ... –

+0

Chacune des affirmations est indépendante. Si après l'ensemble, ue = 1, il sera égal à 1 pour tous les enregistrements de la partie sélectionnée de l'insertion. IOW, cela insérerait tous les enregistrements de dual dans meetup_participation. Il ne changera pas d'un enregistrement à l'autre en duel. Pareil pour les deux sélections. Vous utilisez la valeur renvoyée, pas la "formule" de l'instruction set. –

0

La sélection de ue ne vous indiquera pas si la procédure s'est terminée sans erreur. Vous devriez rechercher les transactions mysql et la gestion des erreurs mysql. http://www.mysqltutorial.org/mysql-error-handling-in-stored-procedures/ est un bon point de départ.

Vous pourriez vous retrouver avec quelque chose comme ça

drop procedure if exists p; 
delimiter // 

CREATE DEFINER=`root`@`localhost` PROCEDURE `p`(
    IN `inue` int, 
    IN `user_id` BIGINT(64), 
    IN `event_id` INT 
) 
LANGUAGE SQL 
NOT DETERMINISTIC 
MODIFIES SQL DATA 
SQL SECURITY DEFINER 
COMMENT '' 
begin 

DECLARE ue INT; 
declare exit handler for sqlexception 
begin 
    rollback; 
    insert into errors (msg) select concat('error ' ,inue,',',user_id,',',event_id); 
end; 

set autocommit = 0; 
#set ue = inue; 
SET ue = EXISTS(SELECT 1 FROM users WHERE fb_uid=user_id) 
    AND EXISTS(SELECT 1 FROM meetup WHERE meet_id=event_id) 
    #AND EXISTS(SELECT 1 FROM meetup WHERE dt > NOW() AND meet_id = event_id) 
    AND EXISTS(SELECT 1 FROM meetup WHERE meet_id = event_id AND ifnull(participants,0) <= max_participants) 
    AND NOT EXISTS(SELECT 1 FROM meetup_participation WHERE fb_uid = user_id AND meet_id = event_id) 
    ; 
select ue; 

if ue = 1 then 

start transaction; 

INSERT INTO meetup_participation SELECT user_id, event_id,user_id, event_id; 
UPDATE users SET events_participated = ifnull(events_participated,0) + 1 WHERE fb_uid=user_id = user_id; 
UPDATE meetup SET participants = ifnull(participants,0) + 1 WHERE meet_id = event_id ; 

commit; 

end if; 

SELECT ue AS response; 

end // 

Le tableau d'erreur ressemble à ceci

CREATE TABLE `errors` (
    `msg` varchar(2000) DEFAULT NULL, 
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 

Remarque Je ne suggère pas que c'est une solution appropriée à votre site, vous devez faire la recherche et comprendre ce qui est le mieux pour vous.