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

PostgreSQL数据表无法插入数据问题求助

PostgreSQL INSERT 报错排查与修复方案

问题描述

尝试点击按钮将表单数据存入PostgreSQL的public.customers表时,多次调整INSERT语句仍出现相同错误,已排查数据类型但未解决。

相关代码

按钮点击事件代码

private void btAdd_Click(object sender, EventArgs e)
{
    try
    {
        string Name = txtName.Text;
        int Age = Convert.ToInt32(this.txtAge.Text);
        string Sex = txtSex.Text;
        int Phone = Convert.ToInt32(this.txtPhone.Text);
        string Type = cmbType.SelectedItem.ToString();
        conn.Open();
        string query = $"INSERT INTO public.customers (name,age,sex,phone,group) VALUES('{Name}','{Age}','{Sex}','{Phone}','{Type}')";

        NpgsqlCommand nCommand = new NpgsqlCommand(query, conn);
        nCommand.ExecuteNonQuery();

        Select();
        MessageBox.Show("Продукт Додано Успішно.", "Додання клієнта", MessageBoxButtons.OK, MessageBoxIcon.Information);
        conn.Close();
    }
    catch (Exception ex)
    {
        MessageBox.Show("Помилка: " + ex.Message, "Помилка", MessageBoxButtons.OK, MessageBoxIcon.Information);
        conn.Close();
    }
}

数据库连接代码

private string connstring = String.Format("Server={0};Port={1};" +
    "User Id={2};Password={3};Database={4};",
    "localhost", 5432, "postgres",
    "123", "fitnessСlub");

private NpgsqlConnection conn;
private string sql;
private NpgsqlCommand cmd;
private DataTable dt;
private int rowIndex = -1;

DataGridView加载代码

private void Select()
{
    try
    {
        conn.Open();
        sql = "SELECT * FROM Customers ORDER BY Custid ASC";
        cmd = new NpgsqlCommand(sql, conn);
        dt = new DataTable();
        dt.Load(cmd.ExecuteReader());
        conn.Close();
        DGV1.DataSource = null;
        DGV1.DataSource = dt;
    }
    catch (Exception ex)
    {
        conn.Close();
        MessageBox.Show("Помилка: " + ex.Message);
    }
}

错误原因分析

  1. 保留字冲突:group是PostgreSQL的内置保留关键字,直接在SQL语句中作为字段名使用会触发语法错误。
  2. SQL字符串拼接的类型错误:将int类型的Age、Phone用单引号包裹,会让PostgreSQL尝试把字符串转换为数值类型,引发类型不匹配错误。
  3. 手机号字段设计不合理:手机号长度通常超过int类型的最大值(2147483647),用int存储会导致数值溢出,应该改用varchar类型。
  4. SQL注入风险:直接拼接用户输入到SQL语句中,存在严重的SQL注入漏洞。

修复方案

1. 修正INSERT语句,处理保留字

将字段名group用双引号包裹,同时改用参数化查询避免类型错误和注入风险:

private void btAdd_Click(object sender, EventArgs e)
{
    try
    {
        string Name = txtName.Text;
        int Age = Convert.ToInt32(this.txtAge.Text);
        string Sex = txtSex.Text;
        // 建议将Phone改为string类型,对应数据库varchar字段
        string Phone = txtPhone.Text;
        string Type = cmbType.SelectedItem.ToString();
        
        conn.Open();
        // 用双引号包裹保留字group,使用参数化查询
        string query = "INSERT INTO public.customers (name, age, sex, phone, \"group\") VALUES (@Name, @Age, @Sex, @Phone, @Type)";

        NpgsqlCommand nCommand = new NpgsqlCommand(query, conn);
        // 添加参数并指定类型
        nCommand.Parameters.AddWithValue("@Name", Name);
        nCommand.Parameters.AddWithValue("@Age", Age);
        nCommand.Parameters.AddWithValue("@Sex", Sex);
        nCommand.Parameters.AddWithValue("@Phone", Phone);
        nCommand.Parameters.AddWithValue("@Type", Type);
        
        nCommand.ExecuteNonQuery();

        Select();
        MessageBox.Show("客户添加成功。", "添加客户", MessageBoxButtons.OK, MessageBoxIcon.Information);
        conn.Close();
    }
    catch (Exception ex)
    {
        MessageBox.Show("错误: " + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
        if (conn.State == System.Data.ConnectionState.Open)
            conn.Close();
    }
}

2. 数据库表结构优化

  • 将group字段重命名为customer_group(或其他非保留字),避免后续重复遇到保留字问题。
  • 将phone字段的数据类型从int改为varchar(20),适配手机号长度需求。

3. 额外优化建议

  • 对用户输入做合法性校验,比如年龄必须是正整数,手机号格式验证等,避免无效数据进入数据库。
  • 使用using语句自动管理数据库连接和命令对象,避免连接泄漏:
using (var conn = new NpgsqlConnection(connstring))
{
    conn.Open();
    using (var cmd = new NpgsqlCommand(query, conn))
    {
        // 参数设置与执行
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 12:47:52