2016-02-22 5 views
0

Je n'arrive pas à comprendre pourquoi la même requête qui s'exécute en dehors d'un processus mysql ne retourne pas les mêmes données à l'intérieur.L'instruction MySQL select dans la procédure stockée renvoie des résultats différents de ceux obtenus en dehors de la procédure

Voici le proc.

DELIMITER $$ 

USE `poll_app`$$ 

DROP PROCEDURE IF EXISTS `record_new_vote`$$ 

CREATE DEFINER=`somemysqluser`@`%` PROCEDURE `record_new_vote`(
    p_member_id INT (10), 
    p_option_ids VARCHAR(255), -- 12,13,14,15 
    p_option_id INT (10), 
    p_stream_id INT (10), 
    p_scene_id INT (10) 
    ) 
BEGIN 

    DECLARE _user_already_voted VARCHAR(255); 
    DECLARE _update_off_id INT; 
    DECLARE _update_on_id INT; 

    -- 1. Query to figure out what to update 

     SELECT 
      p_member_id, p_option_ids, p_option_id, p_stream_id, p_scene_id; 

     SET SESSION group_concat_max_len = 1000000; 

     SELECT 
      GROUP_CONCAT(selections.status, "~~~", selections.id, "~~~", selections.option_id), 
      GROUP_CONCAT(IF(selections.status = "ON", id, NULL)), 
      GROUP_CONCAT(IF(selections.status = "OFF" && selections.option_id = p_option_id, selections.id, NULL)) 
     INTO 
      _user_already_voted, _update_off_id, _update_on_id 
     FROM 
      selections 
     WHERE 
      selections.member_id = p_member_id 
     AND 
      selections.option_id IN (p_option_ids) 
     AND 
      selections.stream_id = p_stream_id 
     AND 
      selections.scene_id = p_scene_id; 

    -- 2. Check to see if the user has already voted on the poll or not 


     IF (_user_already_voted IS NOT NULL) THEN 

      SELECT 
       _user_already_voted, _update_off_id, _update_on_id;   
     END IF; 
    END$$ 

DELIMITER ; 

Voici ce qu'il génère

[ [ RowDataPacket { 
     p_member_id: 107, 
     p_option_ids: '1005,1006,1007,1008', 
     p_option_id: 1007, 
     p_stream_id: 7, 
     p_scene_id: 1 } ], 
    [ RowDataPacket { 
     _user_already_voted: 'OFF~~~451~~~1005', 
     _update_off_id: NULL, 
     _update_on_id: NULL } ], 

Quand je lance la requête de sélection en dehors de la proc (avec les mêmes données enfichés)

SELECT 
     GROUP_CONCAT(`status`, "~~~", id, "~~~", option_id) AS "selections", 
     GROUP_CONCAT(IF(`status` = "ON", id, NULL)) AS "id_to_turn_status_off", 
     GROUP_CONCAT(IF(`status` = "OFF" && option_id = 1007, id, NULL)) AS "id_to_turn_status_on" 
    FROM 
     selections 
    WHERE 
     member_id = 107 
    AND 
     option_id IN (1005,1006,1007,1008) 
    AND 
     stream_id = 7 
    AND 
     scene_id = 1 

Résultats

selections       id_to_turn_status_off  id_to_turnstatus_on 
OFF~~~451~~~1005,ON~~~452~~~1006   452      null 

Comme vous pouvez le voir, le groupe co La chaîne ncat n'est pas aussi longue et l'id_to_turn_status_off est 452 alors que la variable _update_off_id est NULL lorsque la même requête s'exécute dans le proc.

Je ne peux pas comprendre cela pour la vie de moi, toute aide serait grandement appréciée.

Répondre

0

Heureux que vous figured it out :)

La raison pour laquelle il a semblé en partie parce que le travail est de typecasting.

p_option_ids VARCHAR(255) 
p_option_id INT (10), 

selections.option_id IN (p_option_ids) 

Ceci essaie de trouver un INT dans un VARCHAR. MySQL convertit la chaîne de manière dynamique en int, donc il descend la chaîne jusqu'à ce qu'il trouve un caractère non-numérique et tronque le reste. "1005,1006,1007,1008" convertit à seulement 1005 (tronquant le ", 1006,1007,1008"). C'est pourquoi il trouvait la ligne option_id = 1005 mais pas la ligne option_id = 1007.

1

J'ai compris les gars.

Apparemment

IN("1005,1006,1007,1008") 

ne correspond pas à

IN(1005,1006,1007,1008) 

Dans ma requête à l'intérieur du proc, car le paramètre a accepté était une chaîne qu'il utilisait la version guillemet « 1005,1006, 1007,1008 ", où comme la requête que je courais à l'extérieur était la version non double citation 1005,1006,1007,1008

C'est ce qui a causé la différence.

Je l'ai corrigé en utilisant cette place

FIND_IN_SET(selections.option_id, p_option_ids) 

ou à l'extérieur de la requête

FIND_IN_SET(selections.option_id, "1005,1006,1007,1008")