Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/246.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 影响删除的MySQL存储过程变量名_Php_Mysql_Variables_Stored Procedures - Fatal编程技术网

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

Php 影响删除的MySQL存储过程变量名,php,mysql,variables,stored-procedures,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; S

我在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”子句,只删除遇到的第一行。这意味着当“限制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的prepare和存储过程中传递的参数(例如,在它们前面有一个“x”),那么它就可以正常工作。我是不是遗漏了一些明显的东西?

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


我可以看一下“create procedure removeSubscription”语句吗?当然可以@SQL.injection-我已经更新了原始问题以包含create语句。我不明白为什么变量名后面加一个uu与前面加一个@有什么不同。@prefix是否使变量不够唯一?啊哈,我刚刚找到了答案-它们是会话变量-请参阅@MarkHinch 1-是的,您应该使用局部变量。全局变量可能会被服务器上运行的另一个进程更改,也可能是另一个在同一时间执行的进程。如果发生这种情况,您将有不一致的数据。请注意,全局变量的前缀为@MarkHinch 2-您不应该尝试进行实验:设置@A='A';设置@a='a';选择@A,@A;并亲自查看结果。@MarkHinch 3-如果运行此查询,您将得到答案:set@userid=1234;从订阅中选择*,其中userId=@userId;
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 ;