Оператор выбора MySQL в хранимом процессе возвращает результаты, отличные от внешнего

Я не могу понять, почему точно такой же запрос, который выполняется за пределами процесса mysql, не возвращает те же данные внутри него.

Вот проц.

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 ;

Вот что это выводит

[ [ 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 } ],

Когда я запускаю запрос на выборку вне процедуры (с теми же данными, подключенными)

    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

Результаты

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

Как видите, строка concat группы не такая длинная, и id_to_turn_status_off равен 452, тогда как переменная _update_off_id равна NULL, когда тот же запрос выполняется в proc.

Я не могу понять это для моей жизни, любая помощь будет с благодарностью.

2 ответа

Решение

Рад, что вы поняли это:)

Причина, по которой это, казалось, частично работает, заключается в типизировании.

p_option_ids VARCHAR(255)
p_option_id INT (10),

selections.option_id IN (p_option_ids)

Это пытается найти INT внутри VARCHAR. MySQL динамически преобразует строку в целое число, поэтому она идет вниз по строке до тех пор, пока не найдет нечисловой символ и не урежет остальные. "1005,1006,1007,1008" преобразуется в 1005 (усечение ",1006,1007,1008"). Вот почему он находил строку option_id=1005, но не строку option_id=1007.

Я понял это, ребята.

По-видимому

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

НЕ эквивалентно

IN(1005,1006,1007,1008)

В моем запросе внутри proc, поскольку принимаемый им параметр был строкой, он использовал версию с двойными кавычками "1005,1006,1007,1008", где в качестве запроса, который я выполнял, была версия без двойных кавычек 1005,1006, 1007,1008

Это то, что вызвало разницу.

Я исправил это, используя вместо этого

FIND_IN_SET(selections.option_id, p_option_ids)

или вне запроса

FIND_IN_SET(selections.option_id, "1005,1006,1007,1008")
Другие вопросы по тегам