我有一个存储过程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$$
我希望使用mysqli prepared statement从PHP中调用它。我正在按照代码片段进行操作,但它会给我警告。
$connect=&ConnectDB();
$stmt=$connect->prepare("CALL IsUserPresent(?,?)");
$stmt->bind_param('si',$uid,$userCount);
$stmt->execute();
$toRet = $userCount!=0;
Disconnect($connect);
return $toRet;
警告如下:
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
答案 0 :(得分:4)
存储过程使用预处理语句的方式有点复杂。 PHP manual表示你必须使用会话变量(MySQL会话,而不是PHP)
INOUT / OUT参数
使用会话变量访问INOUT / OUT参数的值。
所以你可以用
来做$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);
<强>注:强>
我建议将此过程重写为具有一个返回INT的IN参数的函数。
答案 1 :(得分:3)
应该是评论,但由于代码格式发布作为答案。
无法评论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$$
使用exists()
,因为它会在找到条目后立即停止。 count()
继续寻找记录,但这不是必需的。
您将参数命名为与列名相同的参数。这对MySQL来说很困惑,应该不惜一切代价避免。好的做法是,用p_
为参数加上前缀,用v_
加上变量和/或变量或参数的类型指示。
为了更好的可读性,我还将参数名称改为驼峰式。
哦,最后总是在问题中包含错误消息。