0

我在 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”),那么它就可以正常工作。我在这里遗漏了一些明显的东西吗?

4

1 回答 1

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 ;
于 2013-07-05T13:25:03.257 回答