慢慢地将MSSQL数据库更改为MySQL,最终的问题如下: -
CREATE DEFINER=`root`@`localhost` PROCEDURE `user_GetUserInRole`(
IN $EMail nvarchar(256),
IN $RoleName nvarchar(256),
INOUT $ReturnStatus bit)
BEGIN
DECLARE $UserId char(38);
DECLARE $RoleId char(38);
DECLARE $this_count INT;
SET $UserId = (SELECT UserId FROM server.`user_Data` WHERE EMail = $EMail);
SET $RoleId = (SELECT RoleId FROM server.`user_Roles` WHERE RoleName = $RoleName);
SET $this_count = (SELECT COUNT(*) FROM user_UsersInRoles WHERE UserId = $UserId AND RoleId = $RoleId);
IF ($this_count > 0) THEN
SET $ReturnStatus = 1;
ELSE
SET $ReturnStatus = 0;
END IF;
END
总是返回0,即使我知道计数等于1.我认为输入变量存在问题,而Select UserId
和Select RoleId
中的Where子句无法正确识别输入变量陈述,但我看不出我对我找到的各种帮助有何不同。
非常感谢任何帮助。
修改
我已经尝试过运行一个简单的插入命令
CREATE DEFINER=`root`@`localhost` PROCEDURE `test`()
BEGIN
INSERT INTO server.`test_table`
VALUES('test', 'test2');
END
这也没有奏效。这让我相信它实际上是PDO调用的一个问题。
$command = "EXEC test";
$stpro = $conn->prepare($command);
$returnvalue = $stpro->execute();
我知道$conn
可以在我的php中直接进行sql调用。
编辑2
因此,结果EXEC
应该是CALL
。这现在适用于测试。只要我将任何参数放入其中,它就会停止工作。有什么想法吗?
答案 0 :(得分:0)
不需要$Email
。使您的参数声明像
IN email nvarchar(256)
更改select
内部程序,如下所示
这
SET $UserId = (SELECT UserId FROM server.`user_Data` WHERE EMail = $EMail);
要
SET @UserId := (SELECT UserId FROM server.`user_Data` WHERE EMail = email);
,你的程序看起来应该是
DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `user_GetUserInRole`(
IN email nvarchar(256),
IN rolename nvarchar(256),
INOUT retstatus bit)
BEGIN
SET @UserId := (SELECT UserId FROM server.`user_Data` WHERE EMail = email);
SET @RoleId := (SELECT RoleId FROM server.`user_Roles`
WHERE RoleName = rolename);
SET @this_count := (SELECT COUNT(*) FROM user_UsersInRoles
WHERE UserId = @UserId AND RoleId = @RoleId);
IF (@this_count > 0) THEN
SET retstatus = 1;
ELSE
SET retstatus = 0;
END IF;
END$$
DELIMITER ;
答案 1 :(得分:0)
好的,就在这个我现在在@meda的那一刻。我以为我是一个单独的答案"避免任何混淆。
目前的程序是: -
CREATE DEFINER=`root`@`localhost` PROCEDURE `user_GetUserInRole`(
IN email nvarchar(256),
IN rolename nvarchar(256),
OUT returnstatus int)
BEGIN
SELECT @UserId := UserId FROM server.`user_data` WHERE EMail = email;
SELECT @RoleId := RoleId FROM server.`user_roles` WHERE RoleName = rolename;
SELECT @this_count := COUNT(*) FROM server.`user_usersinroles` WHERE UserId = @UserId AND RoleId = @RoleId;
IF (@this_count > 0) THEN
SET @returnstatus = 1;
ELSE
SET @returnstatus = 0;
END IF;
END
这是由php发起的: -
$command = "CALL user_GetUserInRole (?, ?, ?)";
$role = "Admin";
$stpro = $conn->prepare($command);
$stpro->bindParam(1, $_SESSION['vaild_user']);
$stpro->bindParam(2, $role);
$stpro->bindParam(3, $returnvalue, PDO::PARAM_INT|PDO::PARAM_INPUT_OUTPUT);
$success = $stpro->execute();
if($success)
{
$returnvalue = $stpro->fetch(PDO::FETCH_ASSOC);
}
如果我从过程中移除OUT returnstatus int
并从php中删除第三个参数,那么它运行得很好,如果我在过程中添加了一个Insert命令用于调试目的,我将从查询中获得正确答案。
但是,只要OUT
返回到语句,整个事情就会崩溃,$success = $stpro->execute();
会返回" false"每次。
答案 2 :(得分:0)
好的,所以万一其他人遇到这个问题,我终于有了答案。问题是PDO不允许您正确地将参数绑定到OUT
变量。因此,您需要运行两个查询才能使CALL
正常运行。这允许通过$output
安排读取变量,然后离开。
$role = "Admin";
$command = "CALL user_GetUserInRole ('" . $_SESSION['vaild_user'] . "', '" . $role . "', @returnvalue)";
$conn->query($command);
$output = $conn->query("SELECT @returnvalue")->fetch(PDO::FETCH_ASSOC);
if ($output["@returnvalue"] == 1)
{
$admin = true;
}
答案 3 :(得分:-1)
PDOStatement::execute将根据存储过程调用的成功或失败返回一个布尔值。
所以$returnvalue
并不是你想的那样,试试这个:
$command = "EXEC test ?";
$param = "123";
$stpro = $conn->prepare($command);
$stpro ->bindParam(1, $param, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 12);
$success = $stpro->execute();
if($success){
$returnvalue = $stpro->fetch(PDO::FETCH_ASSOC);
var_dump($returnvalue);
}else{
echo "execute() failed!";
}