Вызываемая хранимая процедура MySQL через PHP не выполняется должным образом

Это заставило меня одурачить, и я надеюсь, что решение - это "вы знаете, почему это не работает, не так ли?" тип ответа.

Здесь идет: через PHP я вызываю хранимую процедуру MySQL таким образом:

$sql = "CALL sp_test;";
$mysqli->query($sql);

Нет проблем там. Я знаю, что хранимая процедура выполняется.

Вот хранимая процедура, которую я разметил для этого примера, и она все еще вызывает ту же проблему.

DELIMITER \\
DROP PROCEDURE IF EXISTS sp_test\\

CREATE PROCEDURE sp_test()
DETERMINISTIC

BEGIN
DECLARE exit_loop TINYINT(1) DEFAULT 0;
DECLARE v_TableName VARCHAR(50); DECLARE v_ScanID INT(11); DECLARE v_ScanType TINYINT(4); 
    DECLARE v_TitleID INT(11); DECLARE v_VolumeNo INT(11); DECLARE v_IssueNo VARCHAR(10); DECLARE v_IssueDate INT(11); DECLARE v_FIDateUnknown TINYINT(4); DECLARE v_PureHavocScan TINYINT(4);

-- declare cursor for employee email
DECLARE storeroom_cursor CURSOR FOR SELECT TableName, ScanID, ScanType, FIDateUnknown, TitleID, VolumeNo, REPLACE(IssueNo, "\'", "") AS IssueNo, IssueDate FROM t_storeroom ts JOIN t_issueguide tig ON ts.TitleID = tig.ComicTitleID;

-- declare NOT FOUND handler
DECLARE CONTINUE HANDLER FOR NOT FOUND SET exit_loop = TRUE;

OPEN storeroom_cursor;

get_purehavoc: LOOP

    FETCH storeroom_cursor INTO v_TableName, v_ScanID, v_ScanType, v_FIDateUnknown, v_TitleID, v_VolumeNo, v_IssueNo, v_IssueDate;

    IF exit_loop = TRUE THEN 
        LEAVE get_purehavoc;
    END IF;

            CASE v_ScanType

                WHEN '1' AND v_FIDateUnknown = 0 THEN
                    SET @sql_text = CONCAT("SELECT @RowCount := COUNT(*) FROM ", v_TableName, " WHERE ComicTitleID = ", v_TitleID, " AND VolumeNo = ", v_VolumeNo, " AND IssueNo = '", v_IssueNo, "' AND IssueDate = ", v_IssueDate, " AND DiggerExclusive = 1;");

                WHEN '1' AND v_FIDateUnknown = 1 THEN
                    SET @sql_text = CONCAT("SELECT @RowCount := COUNT(*) FROM ", v_TableName, " WHERE ComicTitleID = ", v_TitleID, " AND VolumeNo = ", v_VolumeNo, " AND IssueNo = '", v_IssueNo, "' AND DiggerExclusive = 1;");

                -- WHEN '2' THEN
                    -- Do something

            END CASE;

            PREPARE statement FROM @sql_text;
            EXECUTE statement;  

            -- Setting the PureHavocScan variable to enter into the PREPARE STATEMENT.
            IF @RowCount = 0 THEN 
                SET @PureHavocScan = 1;
            ELSE                    
                SET @PureHavocScan = 0;
            END IF;

            SET @ScanID = v_ScanID;
            SET @TableName = v_TableName;

            -- SET @sql_text = concat("UPDATE t_storeroom SET PureHavocScan = ? WHERE TableName = ? AND ScanID = ? ");
            SET @sql_text = concat("UPDATE t_storeroom SET PureHavocScan = ", @PureHavocScan, " WHERE TableName = '", @TableName, "' AND ScanID = ", @ScanID, ";");
            PREPARE statement FROM @sql_text;
            EXECUTE statement;

END LOOP get_purehavoc;

DEALLOCATE PREPARE stmt;
CLOSE storeroom_cursor; 
END//
DELIMITER ;

Когда я запускаю эту точную хранимую процедуру в моем инструменте администрирования базы данных MySQL (в моем случае Navicat), хранимая процедура работает на 100%, как и предполагалось, и ВСЕ строки, которые должны обновляться, ДОЛЖНЫ обновляться.

Однако когда я запускаю эту точную хранимую процедуру через PHP, обновляются ТОЛЬКО 1 (иногда 2) строка.

Другие хранимые процедуры, которые вызываются точно так же, работают нормально. Это только этот. ЕДИНСТВЕННОЕ различие с тем, что терпит неудачу, заключается в том, что команда MySQL является ОБНОВЛЕНИЕМ, в отличие от SELECTS и INSERTS, которые работают нормально.

Я занимаюсь этим уже два дня и исчерпал все "мои" знания. Так что если кто-то может избавить меня от моих страданий, я буду очень благодарен.

1 ответ

Это CASE утверждение неверно

        CASE v_ScanType

            WHEN '1' AND v_FIDateUnknown = 0 THEN
                SET @sql_text = CONCAT("SELECT @RowCount := COUNT(*) FROM ", v_TableName, " WHERE ComicTitleID = ", v_TitleID, " AND VolumeNo = ", v_VolumeNo, " AND IssueNo = '", v_IssueNo, "' AND IssueDate = ", v_IssueDate, " AND DiggerExclusive = 1;");

            WHEN '1' AND v_FIDateUnknown = 1 THEN
                SET @sql_text = CONCAT("SELECT @RowCount := COUNT(*) FROM ", v_TableName, " WHERE ComicTitleID = ", v_TitleID, " AND VolumeNo = ", v_VolumeNo, " AND IssueNo = '", v_IssueNo, "' AND DiggerExclusive = 1;");

            -- WHEN '2' THEN
                -- Do something

        END CASE;

CASE <expression> WHEN <condition> THEN ... это ярлык для CASE WHEN (<expression>) = (<condition>) THEN ..., Таким образом, ваш код не сравнивается v_ScanType в '1' или же '2'Сравниваю это с ('1' AND v_FIDateUnknown = 0), Так что это просто сравнение переменной с TRUE или же FALSE результат сравнения с v_FIDateUnknown,

Вам нужно написать это без ярлыка.

        CASE

            WHEN v_ScanType = '1' AND v_FIDateUnknown = 0 THEN
                SET @sql_text = CONCAT("SELECT @RowCount := COUNT(*) FROM ", v_TableName, " WHERE ComicTitleID = ", v_TitleID, " AND VolumeNo = ", v_VolumeNo, " AND IssueNo = '", v_IssueNo, "' AND IssueDate = ", v_IssueDate, " AND DiggerExclusive = 1;");

            WHEN v_ScanType = '1' AND v_FIDateUnknown = 1 THEN
                SET @sql_text = CONCAT("SELECT @RowCount := COUNT(*) FROM ", v_TableName, " WHERE ComicTitleID = ", v_TitleID, " AND VolumeNo = ", v_VolumeNo, " AND IssueNo = '", v_IssueNo, "' AND DiggerExclusive = 1;");

            -- WHEN v_ScanType = '2' THEN
                -- Do something

        END CASE;

Я не уверен, почему это приведет к сбою только при вызове процедуры из PHP. Может быть, это просто совпадение. Но трудно рассуждать о процедуре с такой вопиющей ошибкой.

Другие вопросы по тегам