重复键值违反唯一约束(主键)
duplicate key value violates unique constraint (primary key)
您好,我这里有一个程序可以将选中列表框中的选中值存储到数据库中。问题是我总是遇到一个异常,说 "duplicate key value violates unique constraint pk_famcon." 我已经尝试过其他替代方法,但它总是会以这种方式结束。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Npgsql;
namespace WindowsFormsApplication1
{
public partial class Form8 : Form
{
public Form8()
{
InitializeComponent();
this.Load += Form8_Load;
button1.Click += button1_Click;
}
DataSet ds = new DataSet();
private void Form8_Load(object sender, EventArgs e)
{
Populate_DataSet();
FillCheckListBox();
}
private void Populate_DataSet()
{
string connstring = "Server=localhost;Port=5432;User Id=postgres;Password=021393;Database=postgres;";
using (NpgsqlConnection conn = new NpgsqlConnection(connstring))
{
string conditionName = "SELECT * FROM condition";
NpgsqlDataAdapter da = new NpgsqlDataAdapter(conditionName, conn);
da.Fill(ds, "conname");
da.Fill(ds, "conid");
}
}
private void FillCheckListBox()
{
DataRow row1 = null;
int iRowCnt = 0;
checkedListBox1.Items.Clear();
foreach (DataRow row_1 in ds.Tables["conname"].Rows)
{
row1 = row_1;
checkedListBox1.Items.Add(ds.Tables["conname"].Rows[iRowCnt][1]);
iRowCnt = iRowCnt + 1;
}
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("Data has been saved");
if (checkedListBox1.Items.Count > 0)
{
string connstring = ("Server=localhost;Port=5432;User Id=postgres;Password=021393;Database=postgres;");
NpgsqlConnection conn = new NpgsqlConnection(connstring);
conn.Open();
for (int i = 0; i <= checkedListBox1.CheckedItems.Count - 1; i++)
{
NpgsqlCommand cmd = new NpgsqlCommand("Insert into famhistory(famcon) Values (@famcon)", conn);
cmd.Parameters.AddWithValue("@famcon", checkedListBox1.Text);
cmd.ExecuteNonQuery();
string value = checkedListBox1.CheckedItems[i].ToString();
}
MessageBox.Show("Data has been saved");
conn.Close();
}
}
}
}
看看这个循环:
for (int i = 0; i <= checkedListBox1.CheckedItems.Count - 1; i++)
{
NpgsqlCommand cmd = new NpgsqlCommand("Insert into famhistory(famcon) Values (@famcon)", conn);
cmd.Parameters.AddWithValue("@famcon", checkedListBox1.Text);
cmd.ExecuteNonQuery();
string value = checkedListBox1.CheckedItems[i].ToString();
}
您在循环的每次迭代中都将相同的值 (checkedListBox1.Text
) 插入到主键字段中,听上去是这样。在最后一条语句之前,您不会使用 i
(循环中的索引) - 这只是声明并为立即超出范围的局部变量赋值。我怀疑你的意思是:
for (int i = 0; i <= checkedListBox1.CheckedItems.Count - 1; i++)
{
NpgsqlCommand cmd = new NpgsqlCommand("Insert into famhistory(famcon) Values (@famcon)", conn);
string value = checkedListBox1.CheckedItems[i].ToString();
cmd.Parameters.AddWithValue("@famcon", value);
cmd.ExecuteNonQuery();
}
除此之外,还有一些值得改变的地方:
循环条件更常规地写为:
for (int i = 0; i < checkedListBox1.CheckedItems.Count; i++)
...或使用 foreach 循环。
- 你应该每次都使用
using
语句来处理你的命令
- 明确指定参数类型,然后使用
Value
属性 设置参数值通常更清晰
把这些放在一起,你有:
foreach (var item in checkedListBox1.CheckedItems)
{
using (var cmd = new NpgsqlCommand("Insert into famhistory(famcon) Values (@famcon)", conn)
{
cmd.Parameters.Add("@famcon", NpgsqlDbType.Varchar).Value = item.ToString();
cmd.ExecuteNonQuery();
}
}
您好,我这里有一个程序可以将选中列表框中的选中值存储到数据库中。问题是我总是遇到一个异常,说 "duplicate key value violates unique constraint pk_famcon." 我已经尝试过其他替代方法,但它总是会以这种方式结束。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Npgsql;
namespace WindowsFormsApplication1
{
public partial class Form8 : Form
{
public Form8()
{
InitializeComponent();
this.Load += Form8_Load;
button1.Click += button1_Click;
}
DataSet ds = new DataSet();
private void Form8_Load(object sender, EventArgs e)
{
Populate_DataSet();
FillCheckListBox();
}
private void Populate_DataSet()
{
string connstring = "Server=localhost;Port=5432;User Id=postgres;Password=021393;Database=postgres;";
using (NpgsqlConnection conn = new NpgsqlConnection(connstring))
{
string conditionName = "SELECT * FROM condition";
NpgsqlDataAdapter da = new NpgsqlDataAdapter(conditionName, conn);
da.Fill(ds, "conname");
da.Fill(ds, "conid");
}
}
private void FillCheckListBox()
{
DataRow row1 = null;
int iRowCnt = 0;
checkedListBox1.Items.Clear();
foreach (DataRow row_1 in ds.Tables["conname"].Rows)
{
row1 = row_1;
checkedListBox1.Items.Add(ds.Tables["conname"].Rows[iRowCnt][1]);
iRowCnt = iRowCnt + 1;
}
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("Data has been saved");
if (checkedListBox1.Items.Count > 0)
{
string connstring = ("Server=localhost;Port=5432;User Id=postgres;Password=021393;Database=postgres;");
NpgsqlConnection conn = new NpgsqlConnection(connstring);
conn.Open();
for (int i = 0; i <= checkedListBox1.CheckedItems.Count - 1; i++)
{
NpgsqlCommand cmd = new NpgsqlCommand("Insert into famhistory(famcon) Values (@famcon)", conn);
cmd.Parameters.AddWithValue("@famcon", checkedListBox1.Text);
cmd.ExecuteNonQuery();
string value = checkedListBox1.CheckedItems[i].ToString();
}
MessageBox.Show("Data has been saved");
conn.Close();
}
}
}
}
看看这个循环:
for (int i = 0; i <= checkedListBox1.CheckedItems.Count - 1; i++)
{
NpgsqlCommand cmd = new NpgsqlCommand("Insert into famhistory(famcon) Values (@famcon)", conn);
cmd.Parameters.AddWithValue("@famcon", checkedListBox1.Text);
cmd.ExecuteNonQuery();
string value = checkedListBox1.CheckedItems[i].ToString();
}
您在循环的每次迭代中都将相同的值 (checkedListBox1.Text
) 插入到主键字段中,听上去是这样。在最后一条语句之前,您不会使用 i
(循环中的索引) - 这只是声明并为立即超出范围的局部变量赋值。我怀疑你的意思是:
for (int i = 0; i <= checkedListBox1.CheckedItems.Count - 1; i++)
{
NpgsqlCommand cmd = new NpgsqlCommand("Insert into famhistory(famcon) Values (@famcon)", conn);
string value = checkedListBox1.CheckedItems[i].ToString();
cmd.Parameters.AddWithValue("@famcon", value);
cmd.ExecuteNonQuery();
}
除此之外,还有一些值得改变的地方:
循环条件更常规地写为:
for (int i = 0; i < checkedListBox1.CheckedItems.Count; i++)
...或使用 foreach 循环。
- 你应该每次都使用
using
语句来处理你的命令 - 明确指定参数类型,然后使用
Value
属性 设置参数值通常更清晰
把这些放在一起,你有:
foreach (var item in checkedListBox1.CheckedItems)
{
using (var cmd = new NpgsqlCommand("Insert into famhistory(famcon) Values (@famcon)", conn)
{
cmd.Parameters.Add("@famcon", NpgsqlDbType.Varchar).Value = item.ToString();
cmd.ExecuteNonQuery();
}
}