PHP登录调用MySQL存储过程报错求助:参数不匹配问题
解决存储过程调用的参数不匹配问题
嘿,我来帮你搞定这个SQLSTATE[HY093]错误!这个问题的核心是你调用存储过程时,占位符的数量和存储过程实际的参数数量完全不匹配,咱们一步步来修正:
第一步:先修复存储过程本身的问题
你的存储过程里有两个明显的错误,先把它改对:
- 第一个
SELECT count(1)里用了login=v_login and pwd =v_pass,但你的输入参数是v_Mail_UT和v_PW_UT,变量名完全不对,会导致计数永远为0 - 存储过程结尾缺少
END;,语法不完整
修正后的存储过程代码:
CREATE DEFINER=`root`@`localhost` PROCEDURE `get_dati_user`( IN v_Mail_UT VARCHAR(45), IN v_PW_UT VARCHAR(20), OUT v_Cod_Workgroup VARCHAR(25), OUT v_Nome_UT VARCHAR(25), OUT v_Cog_UT VARCHAR(25), OUT v_Permessi_Utente VARCHAR(45), OUT v_Data_Iscrizione VARCHAR(45), OUT v_Tel_UT VARCHAR(45), OUT v_count int ) BEGIN -- 修正变量名,匹配输入参数 SELECT count(1) INTO v_count FROM t_utenti WHERE login = v_Mail_UT AND pwd = v_PW_UT; IF (v_count > 0) THEN SELECT `tab01_utenti`.`Cod_Workgroup`, `tab01_utenti`.`Nome_UT`, `tab01_utenti`.`Cog_UT`, `tab01_utenti`.`Permessi_Utente`, `tab01_utenti`.`Data_Iscrizione`, `tab01_utenti`.`Tel_UT` INTO v_Cod_Workgroup, v_Nome_UT, v_Cog_UT, v_Permessi_Utente, v_Data_Iscrizione, v_Tel_UT FROM tab01_utenti WHERE Mail_UT = v_Mail_UT AND PW_UT = v_PW_UT; END IF; END; -- 补上缺失的END;
第二步:修正PHP代码的参数绑定问题
你的存储过程一共有9个参数(2个IN,7个OUT),但你原来的CALL get_dati_user(?, ?)只写了2个占位符,这就是错误的根源。需要把所有参数的占位符都加上,然后正确绑定每个变量:
修正后的PHP代码:
<?php include 'connectdb.php'; error_reporting(E_ALL); ini_set('display_errors', 'On'); // 1. 存储过程有9个参数,所以要写9个占位符 $sql = 'CALL get_dati_user(?, ?, ?, ?, ?, ?, ?, ?, ?)'; $stmt = $conn->prepare($sql); // 从表单获取输入参数 $v_Email_UT = $_POST['v_Email_UT']; $v_PW_UT = $_POST['v_PW_UT']; // 2. 提前声明所有OUT变量(必须初始化,否则绑定会出问题) $v_Cod_Workgroup = ''; $v_Nome_UT = ''; $v_Cog_UT = ''; $v_Permessi_Utente = ''; $v_Data_Iscrizione = ''; $v_Tel_UT = ''; $v_count = 0; // 3. 绑定参数:IN参数用PARAM_STR,OUT参数用PARAM_INPUT_OUTPUT // 第1、2位是IN参数 $stmt->bindParam(1, $v_Email_UT, PDO::PARAM_STR, 45); $stmt->bindParam(2, $v_PW_UT, PDO::PARAM_STR, 20); // 第3到9位是OUT参数 $stmt->bindParam(3, $v_Cod_Workgroup, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 25); $stmt->bindParam(4, $v_Nome_UT, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 25); $stmt->bindParam(5, $v_Cog_UT, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 25); $stmt->bindParam(6, $v_Permessi_Utente, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 45); $stmt->bindParam(7, $v_Data_Iscrizione, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 45); $stmt->bindParam(8, $v_Tel_UT, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 45); $stmt->bindParam(9, $v_count, PDO::PARAM_INT|PDO::PARAM_INPUT_OUTPUT, 10); // 执行存储过程 $stmt->execute(); // 执行完后,你就可以直接使用这些OUT变量了,比如: if ($v_count > 0) { echo "登录成功!用户名:{$v_Nome_UT} {$v_Cog_UT}"; } else { echo "邮箱或密码错误"; } ?>
额外提醒
- 注意存储过程里的表名:你第一个查询用的是
t_utenti,第二个查询用的是tab01_utenti,确认这两个表是正确的,避免表名错误 - 密码存储建议:不要明文存储密码,应该用
password_hash()和password_verify()来处理,这是安全最佳实践
内容的提问来源于stack exchange,提问作者Domenico Schitti
相关产品推荐
相关产品推荐

