简体   繁体   English

PHP mysqli为带out参数的存储过程准备了语句

[英]PHP mysqli prepared statement for stored procedure with out parameter

I have a stored procedure IsUserPresent like: 我有一个存储过程IsUserPresent像:

DELIMITER $$
CREATE PROCEDURE IsUserPresent(
    in userid varchar (150),
    out isPresent bit
)
BEGIN
    SET isPresent=0;
    SELECT COUNT(*)
    INTO isPresent
    FROM users_table
    WHERE users_table.userid=userid;
END$$

and I want to call it from PHP using mysqli prepared statement. 并且我想使用mysqli prepare语句从PHP调用它。 I am doing it following code snippet but it gives me warning. 我正在执行以下代码段,但它给了我警告。

$connect=&ConnectDB();
$stmt=$connect->prepare("CALL IsUserPresent(?,?)");
$stmt->bind_param('si',$uid,$userCount);
$stmt->execute();
$toRet = $userCount!=0;
Disconnect($connect);
return $toRet;

Warnings are as follow: 警告如下:

Premature end of data (mysqlnd_wireprotocol.c:1112)
Warning: mysqli_stmt::execute(): RSET_HEADER packet 1 bytes shorter than expected
Warning: mysqli_stmt::execute(): Error reading result set's header

The way stored procedures work with prepared statements is a bit more complicated. 存储过程与准备好的语句一起工作的方式要复杂一些。 PHP manual states that you've got to use session variables (MySQL sessions, not PHP) PHP手册指出您必须使用会话变量(MySQL会话,而不是PHP)

INOUT/OUT parameter INOUT / OUT参数

The values of INOUT/OUT parameters are accessed using session variables. 使用会话变量可以访问INOUT / OUT参数的值。

So you could do it with 所以你可以做到

$connect=&ConnectDB();
// bind the first parameter to the session variable @uid
$stmt = $connect->prepare('SET @uid := ?');
$stmt->bind_param('s', $uid);
$stmt->execute();

// bind the second parameter to the session variable @userCount
$stmt = $connect->prepare('SET @userCount := ?');
$stmt->bind_param('i', $userCount);
$stmt->execute();

// execute the stored Procedure
$result = $connect->query('call IsUserPresent(@uid, @userCount)');

// getting the value of the OUT parameter
$r = $connect->query('SELECT @userCount as userCount');
$row = $r->fetch_assoc();               

$toRet = ($row['userCount'] != 0);

Remark: 备注:

I recommend to rewrite this procedure as a function with one IN parameter that returns INT. 我建议将此过程重写为带有一个返回INT的IN参数的函数。

Should be a comment, but due to code formatting posting as answer. 应该是注释,但由于代码格式过帐而作为答案。

Can't comment on the PHP code, I'm no programmer, but your procedure should be more like this: 无法评论PHP代码,我不是程序员,但是您的过程应该更像这样:

DELIMITER $$
CREATE PROCEDURE IsUserPresent(
    in p_userId varchar (150),
    out p_isPresent bit
)
BEGIN

    SELECT EXISTS (SELECT 1 FROM users_table WHERE user_table.userid = p_userId) 
    INTO p_isPresent;

END$$

Use exists() , since it stops as soon as an entry is found. 使用exists() ,因为它会在找到条目后立即停止。 count() continues to look for records, although this isn't necessary. 尽管没有必要, count()继续寻找记录。

And you named a parameter the same as your column name. 您为参数命名的名称与列名相同。 This is confusing for MySQL and should be avoided at all costs. 这对于MySQL来说是令人困惑的,应该不惜一切代价避免。 Good practice is, to prefix parameters with p_ and variables with v_ and/or some indications of what type the variable or parameter is. 优良作法是在参数前加上p_并在变量前加上v_和/或对变量或参数的类型进行一些指示。

For better readability I also changed the paramter names to camel case. 为了提高可读性,我还将参数名称更改为驼峰式。

Oh, and finally always include error messages in questions. 哦,最后总是在问题中包含错误消息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM