使用带子句中的输入变量的MySQL存储过程

时间:2014-06-04 13:33:24

标签: php mysql sql sql-server

慢慢地将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 UserIdSelect 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。这现在适用于测试。只要我将任何参数放入其中,它就会停止工作。有什么想法吗?

4 个答案:

答案 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!"; 
}