【发布时间】:2019-05-18 02:54:46
【问题描述】:
这个问题让我很困惑,我希望解决方案是“你知道为什么这不起作用,不是吗?”回复类型。
这里是:我通过 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。
我已经在这里工作了两天,并且已经用尽了所有“我的”知识。因此,如果有人能让我摆脱痛苦,我将不胜感激。
【问题讨论】:
-
如何确定只有一(或有时是两)行得到更新?
-
CASE语句不正确。 -
小心更新您的光标正在迭代的表stackoverflow.com/questions/30365427/…
-
Ro Achterberg - 当我通过我的“数据库管理工具”运行相同的程序时,我收到了所有“预期”的结果(即 100 多行得到正确更新)。但是在执行 PHP CALL 命令之后,有问题的表只会更新“1”行。另一个“不同”表可能会更新“2”行。我使用了很多表,并且成功的未注明日期的行数永远不会超过“2”。我开始认为问题正在发生,因为我正在更新我正在迭代的表(正如 LUFC 所建议的那样。
-
lufc - 我调查了您的“迭代游标”建议(即 INSENSITIVE 和 ASENSITIVE 游标)。我什至尝试创建一个新的临时表并使用新信息对其进行更新,但它仍然以完全相同的方式失败。极好的!可以在每次迭代中更新的行只会更新自身,不会更新其他行。所以表不能以某种方式重新排序自己,就像更新正在迭代的表时可能发生的那样。必须有其他一些我在这里根本看不到的东西。不过感谢您的建议。
标签: php mysql stored-procedures