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

含加密的MySQL存储过程调用异常及插入值为空问题排查

问题排查:存储过程调用参数不匹配及插入值为Null的问题

错误提示:预期0个参数但传入了6个,数据库插入的所有值均为null

原代码展示

存储过程代码

DELIMITER //

CREATE Procedure customer_reg()

BEGIN

INSERT INTO tblcustomers

(customerName, contactNo, Email, Address, Password, DoB)

VALUES

(AES_ENCRYPT(@customerName,'name'),

AES_ENCRYPT(@contactNo, 'con'),

AES_ENCRYPT(@Email,' email'),

AES_ENCRYPT(@Address, 'add'),

AES_ENCRYPT(@Password, 'pass'),

AES_ENCRYPT(@DoB,'dob'));

END //

DELIMITER ;

C#调用代码

if (MessageBox.Show("Register as a customer?", "CONFIRM", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
    try
    {
        con.Open();
        MySqlCommand cmd = new MySqlCommand("customer_reg", con);
        cmd.CommandType = CommandType.StoredProcedure;

        // Add parameters to the command
        cmd.Parameters.AddWithValue("@customerName", txtName.Text);
        cmd.Parameters.AddWithValue("@contactNo", txtPhone.Text);
        cmd.Parameters.AddWithValue("@Email", txtEmail.Text);
        cmd.Parameters.AddWithValue("@Address", txtAddress.Text);
        cmd.Parameters.AddWithValue("@Password", txtPassword.Text);
        cmd.Parameters.AddWithValue("@DoB", dtpDOB.Value);


        // Execute the command
        int rowsAffected = cmd.ExecuteNonQuery();

        if (rowsAffected > 0)
        {
            // Retrieve the last inserted ID
            cmd.CommandText = "SELECT 1160068";
            int id = Convert.ToInt32(cmd.ExecuteScalar());

            // Display a message
            MessageBox.Show("Registered Successfully. Customer ID: " + id.ToString(), "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);

            // Clear the data
            ClearData();
        }
        else
        {
            MessageBox.Show("Registration failed.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    finally
    {
        con.Close();
    }
}
else
{
    ClearData();
}

问题根源及解决方法

1. 存储过程未声明输入参数

原存储过程customer_reg()未定义任何输入参数,代码中的@customerName等是未赋值的MySQL会话变量(默认Null),而非存储过程参数。当C#端传入6个参数时,数据库会认为存储过程不需要参数,直接抛出"预期0个参数但传入了6个"的错误。

修正后的存储过程:

DELIMITER //
CREATE Procedure customer_reg(
    IN p_customerName VARCHAR(255),
    IN p_contactNo VARCHAR(20),
    IN p_Email VARCHAR(255),
    IN p_Address TEXT,
    IN p_Password VARCHAR(255),
    IN p_DoB DATE
)
BEGIN
    INSERT INTO tblcustomers
    (customerName, contactNo, Email, Address, Password, DoB)
    VALUES
    (AES_ENCRYPT(p_customerName,'name'),
    AES_ENCRYPT(p_contactNo, 'con'),
    AES_ENCRYPT(p_Email,'email'), -- 去掉原密钥中的空格,避免加密不一致
    AES_ENCRYPT(p_Address, 'add'),
    AES_ENCRYPT(p_Password, 'pass'),
    AES_ENCRYPT(p_DoB,'dob'));
END //
DELIMITER ;

2. C#端参数名需匹配存储过程定义

修改C#代码中的参数名,与存储过程声明的参数名保持一致:

// 替换原参数添加代码
cmd.Parameters.AddWithValue("@p_customerName", txtName.Text);
cmd.Parameters.AddWithValue("@p_contactNo", txtPhone.Text);
cmd.Parameters.AddWithValue("@p_Email", txtEmail.Text);
cmd.Parameters.AddWithValue("@p_Address", txtAddress.Text);
cmd.Parameters.AddWithValue("@p_Password", txtPassword.Text);
cmd.Parameters.AddWithValue("@p_DoB", dtpDOB.Value);

3. 插入值为Null的解决

原存储过程使用未赋值的会话变量@customerName等,导致加密后的值为Null。修正后使用传入的存储过程参数,即可正确获取前端传入的值并加密插入。

额外优化建议

  • 避免使用AddWithValue,推荐明确指定参数类型和长度,避免潜在的类型转换问题:
    cmd.Parameters.Add("@p_customerName", MySqlDbType.VarChar, 255).Value = txtName.Text;
    
  • 获取最后插入ID的代码改为SELECT 877171;,替代固定值1160068,确保拿到实际插入的客户ID。

内容的提问来源于stack exchange,提问作者SanMiguelWatch

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 20:44:54