通过PHP调用的MySQL存储过程无法正确执行

时间:2018-12-17 17:32:21

标签: php mysql stored-procedures

这个让我很烦,我希望解决方案是“您知道为什么它不起作用,不是吗?”回复类型。

在这里:通过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命令是UPDATE,而不是运行良好的SELECTS和INSERTS。

我已经在这里待了两天了,用尽了所有“我的”知识。因此,如果有人能让我摆脱痛苦,我将不胜感激。

1 个答案:

答案 0 :(得分:0)

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进行比较的FALSEv_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调用过程时才导致失败。也许这只是一个巧合。但是很难推断出这样一个带有明显错误的过程。