You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP登录调用MySQL存储过程报错求助:参数不匹配问题

解决存储过程调用的参数不匹配问题

嘿,我来帮你搞定这个SQLSTATE[HY093]错误!这个问题的核心是你调用存储过程时,占位符的数量和存储过程实际的参数数量完全不匹配,咱们一步步来修正:

第一步:先修复存储过程本身的问题

你的存储过程里有两个明显的错误,先把它改对:

  1. 第一个SELECT count(1)里用了login=v_login and pwd =v_pass,但你的输入参数是v_Mail_UT和v_PW_UT,变量名完全不对,会导致计数永远为0
  2. 存储过程结尾缺少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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:40:09