Я маю збережену процедуру 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$$
і я хочу назвати його з PHP за допомогою mysqli підготовленої операції. Я роблю це після фрагмента коду, але це дає мені попередження.
$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
Відповіді:
4 для відповіді № 1Спосіб роботи збережених процедур з підготовленими виписками є дещо складнішим. PHP посібник стверджує, що ви повинні використовувати змінні сеансу (сесії 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);
Зауваження:
Я рекомендую переписати цю процедуру як функцію з одним параметром IN, який повертає INT.
3 для відповіді № 2
Повинен бути коментар, але з-за відправлення форматування коду як відповідь.
Не можу прокоментувати 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_
та / або деякі вказівки того, що тип змінної або параметр.
Для кращої читаності я також змінив імена параметрів на випадок верблюдів.
Ну, і нарешті завжди включати повідомлення про помилки в питаннях.