MySQL存储过程变量名称影响删除

时间:2013-07-05 09:24:26

标签: php mysql variables stored-procedures

我遇到了MySQL存储过程的一个非常有趣的问题。程序如下:

DROP PROCEDURE IF EXISTS `removeSubscription`;
DELIMITER ;;
CREATE DEFINER=`root`@`%` PROCEDURE `removeSubscription`(IN `userId` int,IN `channelId` int,IN `channelTypeTitle` varchar(255))

BEGIN

SET @userId = userId;
SET @channelId = channelId;
SET @channelTypeTitle = channelTypeTitle;

DELETE FROM subscriptions 
WHERE 
    userid = @userId AND 
    channelid = @channelId AND 
    channeltypeid = (SELECT id FROM channeltypes WHERE `name` = @channelTypeTitle) 
LIMIT 1;

END
;;
DELIMITER ;

当这被称为PHP的存储过程时,忽略所有'WHERE'子句,只是删除它遇到的第一行。这意味着当省略'LIMIT 1'时,它会从表中删除所有内容:s

这是PHP:

$stmt = $db->prepare("CALL removeSubscription(:userId, :channelId, :channelTypeTitle)");

$stmt->bindValue('userId', $userId);
$stmt->bindValue('channelId', $channelId);
$stmt->bindValue('channelTypeTitle', $channelTypeTitle);

$stmt->execute();

奇怪的是,如果我在PHP的准备和存储过程中重命名传递的参数(例如,在它们之前有一个'x'),那么它可以正常工作。我错过了一些明显的东西吗?

1 个答案:

答案 0 :(得分:2)

不要重用变量名称在其范围内应该是唯一的...并且不要在存储过程中使用全局变量(它们具有全局范围,因此您应该使用本地变量)。 ..

DROP PROCEDURE IF EXISTS `removeSubscription`;
DELIMITER ;;
CREATE DEFINER=`root`@`%` PROCEDURE `removeSubscription`(IN `userId` int,IN `channelId` int,IN `channelTypeTitle` varchar(255))

BEGIN

declare userId_, channelId_, channelTypeTitle_ integer;

SET userId_ = userId;
SET channelId_ = channelId;
SET channelTypeTitle_ = channelTypeTitle;

DELETE FROM subscriptions 
WHERE 
    userid = userId_ AND 
    channelid = channelId_ AND 
    channeltypeid = (SELECT id FROM channeltypes WHERE `name` = channelTypeTitle_) 
LIMIT 1;

END
;;
DELIMITER ;
相关问题