Вызываемая хранимая процедура 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. Может быть, это просто совпадение. Но трудно рассуждать о процедуре с такой вопиющей ошибкой.