utilizarlos statement sentencias procedimientos procedimiento prepared preparadas bind_param almacenados almacenado php mysql stored-procedures mysqli prepared-statement

statement - Sentencia preparada PHP mysqli para procedimiento almacenado sin parámetro



sentencias preparadas php mysqli (2)

Tengo un procedimiento almacenado IsUserPresent como:

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$$

y quiero llamarlo desde PHP usando la declaración preparada de mysqli. Lo hago siguiendo un fragmento de código pero me da una advertencia.

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

Las advertencias son las siguientes:

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


Debería ser un comentario, pero debido a la publicación del formato del código como respuesta.

No puedo comentar sobre el código PHP, no soy programador, pero su procedimiento debería ser más como este:

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() , ya que se detiene tan pronto como se encuentra una entrada. count() continúa buscando registros, aunque esto no es necesario.

Y nombró un parámetro igual que su nombre de columna. Esto es confuso para MySQL y debe evitarse a toda costa. Una buena práctica es, prefijar parámetros con p_ y variables con v_ y / o algunas indicaciones de qué tipo es la variable o parámetro.

Para una mejor legibilidad, también cambié los nombres de los parámetros a camel case.

Ah, y finalmente siempre incluyen mensajes de error en las preguntas.


La forma en que los procedimientos almacenados funcionan con declaraciones preparadas es un poco más complicado. El manual de PHP indica que debe usar variables de sesión (sesiones de MySQL, no PHP)

Parámetro INOUT / OUT

Se accede a los valores de los parámetros INOUT / OUT utilizando variables de sesión.

Entonces podrías hacerlo con

$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);

Observación:

Recomiendo reescribir este procedimiento como una función con un parámetro IN que devuelve INT.