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); } }
错误原因分析
- 保留字冲突:
group是PostgreSQL的内置保留关键字,直接在SQL语句中作为字段名使用会触发语法错误。 - SQL字符串拼接的类型错误:将
int类型的Age、Phone用单引号包裹,会让PostgreSQL尝试把字符串转换为数值类型,引发类型不匹配错误。 - 手机号字段设计不合理:手机号长度通常超过
int类型的最大值(2147483647),用int存储会导致数值溢出,应该改用varchar类型。 - 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
相关产品推荐
相关产品推荐

