尝试向数据库添加新记录时在 C# 中自动生成和自动增量 ID
Auto generate and AutoIncrement ID in C# when trying to add new record to database
我正在使用此代码 select 来自数据库的 maxID table 并且每次我想添加一条新记录时,自动生成的 ID 都不是最后一个 +1。
public formularAddCompanie()
{
InitializeComponent();
try
{
string cs = "Data Source=CODRINMA\CODRINMA;Initial Catalog=TrafficManager;Integrated Security=True";
string select = "SELECT max(IDCompanie) FROM Companii";
using (SqlConnection con = new SqlConnection(cs))
{
con.Open();
SqlCommand cmd2 = new SqlCommand(select, con);
SqlDataReader sda = cmd2.ExecuteReader();
DataTable idmax = new DataTable("idmax");
idmax.Load(sda);
if (idmax.Rows[0][0].ToString().Trim() == "") { txtID.Text = "1"; }
else { txtID.Text = (int.Parse(idmax.Rows[0][0] .ToString() + 1).ToString()); }
}
}
catch (Exception er) { MessageBox.Show(er.Message); }
}
制造select离子的table看起来像这样:
IDCompany Name Address City RegNo
1 A Street NY 123
每次我想添加一条新记录时,自动生成的 ID 是这样的:11, 111, 1111。它取最后一个 ID 并在其旁边添加另一个 1。我错过了什么?
idmax.Rows[0][0].ToString() + 1
生成 string
,而不是 int
。
你可以试试
txtID.Text = (Convert.ToInt32(idmax.Rows[0][0]) + 1).ToString();
试试这个片段:
将您的 String
转换为 Int
。 String
与 +
运算符将 con-cat 并与 int
它将添加数字。
if (idmax.Rows[0][0].ToString().Trim() == "") { txtID.Text = "1"; }
else {
txtID.Text = Convert.ToString(Convert.ToInt32(idmax.Rows[0][0] .ToString())+1); }
有趣的是,请注意
string a = "The meaning of life is " + 42;
将 42 转换为字符串,创建结果
a == "The meaning of life is 42"
看这段代码:
(int.Parse(idmax.Rows[0][0] .ToString() + 1).ToString()); }
您正在将 idmax.Rows[0][0] 转换为字符串,并将 +1 添加到字符串 的末尾 而不是整数值。尝试
(int.Parse(idmax.Rows[0][0].ToString()) + 1).ToString(); }
请注意,idmax.Rows[0][0]
中应该已经有一个整数(正如评论中指出的那样)。如果是这样,您可以简化为
(idmax.Rows[0][0] + 1).ToString(); }
我只是添加这个,因为 none 似乎关心发布者发布的代码的弱点。
首先,如果您想查找将分配给 ID 列的下一个自动增量值,则 MAX 函数不可靠。并发可能会对任何使用 MAX 的模式造成严重破坏。假设另一个用户已经为自己的 INSERT 操作检索了 MAX,然后根据两台计算机的相对速度,您或另一个用户将为 IDCompany 字段插入一个重复值。
执行此常见任务的唯一正确方法是对 IDCompany 列使用 IDENTITY 属性,当您需要插入新记录时,您应该这样写
try
{
string insert = "INSERT INTO Companii (Name,Address,City,RegNo)
VALUES(@name,@address,@city,@regno);
SELECT SCOPE_IDENTITY()";
using (SqlConnection con = new SqlConnection(cs))
using (SqlCommand cmd = new SqlCommand(insert, con))
{
con.Open();
cmd.Parameters.Add("@name", SqlDbType.NVarChar).Value = txtBoxCity.Text;
.... and on for the other parameters ....
int companyID = Convert.ToInt32(cmd.ExecuteScalar());
... work with the just added company if required
}
}
catch (Exception er)
{ MessageBox.Show(er.Message); }
SCOPE_IDENTITY 将 return 最后一个标识值插入同一范围内的标识列中,在此上下文范围内表示您的命令使用的连接。
无论如何,如果仍然需要 MAX 方法,那么可以使用修改后的查询和 SqlCommand.ExecuteScalar 来简化代码,而不是构建 SqlDataReader、填充数据表、尝试解析结果如果
string getMax = @"select COALESCE(MAX(IDCompany), 0) + 1 AS maxPlusOne
from Companii"
using(SqlConnection cnn = new SqlConnection(.....))
using(SqlCommand cmd = new SqlCommand(getMax, cnn))
{
cnn.Open();
int nextCompanyID = Convert.ToInt32(cmd.ExecuteScalar());
}
The COALESCE function检查MAX函数的结果,如果是NULL returns第二个参数(这里是0),那么只要自增1就可以直接从数据库中得到下一个MAX . ExecuteScalar 将只调用 returning maxPlusOne
别名字段
试试这个,我的 ID 格式是 USR001.The 代码将根据数据库中的最后一个 ID 生成自动 ID。如果数据库中的最后一个 id 是 USR001,代码将生成 USR002 并将 id 放入文本框
con.Open();
string sqlQuery = "SELECT TOP 1 kode_user from USERADM order by kode_user desc";
SqlCommand cmd = new SqlCommand(sqlQuery, con);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
string input = dr["kode_user"].ToString();
string angka = input.Substring(input.Length - Math.Min(3, input.Length));
int number = Convert.ToInt32(angka);
number += 1;
string str = number.ToString("D3");
txtKodeUser.Text = "USR" + str;
}
con.Close();
我正在使用此代码 select 来自数据库的 maxID table 并且每次我想添加一条新记录时,自动生成的 ID 都不是最后一个 +1。
public formularAddCompanie()
{
InitializeComponent();
try
{
string cs = "Data Source=CODRINMA\CODRINMA;Initial Catalog=TrafficManager;Integrated Security=True";
string select = "SELECT max(IDCompanie) FROM Companii";
using (SqlConnection con = new SqlConnection(cs))
{
con.Open();
SqlCommand cmd2 = new SqlCommand(select, con);
SqlDataReader sda = cmd2.ExecuteReader();
DataTable idmax = new DataTable("idmax");
idmax.Load(sda);
if (idmax.Rows[0][0].ToString().Trim() == "") { txtID.Text = "1"; }
else { txtID.Text = (int.Parse(idmax.Rows[0][0] .ToString() + 1).ToString()); }
}
}
catch (Exception er) { MessageBox.Show(er.Message); }
}
制造select离子的table看起来像这样:
IDCompany Name Address City RegNo
1 A Street NY 123
每次我想添加一条新记录时,自动生成的 ID 是这样的:11, 111, 1111。它取最后一个 ID 并在其旁边添加另一个 1。我错过了什么?
idmax.Rows[0][0].ToString() + 1
生成 string
,而不是 int
。
你可以试试
txtID.Text = (Convert.ToInt32(idmax.Rows[0][0]) + 1).ToString();
试试这个片段:
将您的 String
转换为 Int
。 String
与 +
运算符将 con-cat 并与 int
它将添加数字。
if (idmax.Rows[0][0].ToString().Trim() == "") { txtID.Text = "1"; }
else {
txtID.Text = Convert.ToString(Convert.ToInt32(idmax.Rows[0][0] .ToString())+1); }
有趣的是,请注意
string a = "The meaning of life is " + 42;
将 42 转换为字符串,创建结果
a == "The meaning of life is 42"
看这段代码:
(int.Parse(idmax.Rows[0][0] .ToString() + 1).ToString()); }
您正在将 idmax.Rows[0][0] 转换为字符串,并将 +1 添加到字符串 的末尾 而不是整数值。尝试
(int.Parse(idmax.Rows[0][0].ToString()) + 1).ToString(); }
请注意,idmax.Rows[0][0]
中应该已经有一个整数(正如评论中指出的那样)。如果是这样,您可以简化为
(idmax.Rows[0][0] + 1).ToString(); }
我只是添加这个,因为 none 似乎关心发布者发布的代码的弱点。 首先,如果您想查找将分配给 ID 列的下一个自动增量值,则 MAX 函数不可靠。并发可能会对任何使用 MAX 的模式造成严重破坏。假设另一个用户已经为自己的 INSERT 操作检索了 MAX,然后根据两台计算机的相对速度,您或另一个用户将为 IDCompany 字段插入一个重复值。
执行此常见任务的唯一正确方法是对 IDCompany 列使用 IDENTITY 属性,当您需要插入新记录时,您应该这样写
try
{
string insert = "INSERT INTO Companii (Name,Address,City,RegNo)
VALUES(@name,@address,@city,@regno);
SELECT SCOPE_IDENTITY()";
using (SqlConnection con = new SqlConnection(cs))
using (SqlCommand cmd = new SqlCommand(insert, con))
{
con.Open();
cmd.Parameters.Add("@name", SqlDbType.NVarChar).Value = txtBoxCity.Text;
.... and on for the other parameters ....
int companyID = Convert.ToInt32(cmd.ExecuteScalar());
... work with the just added company if required
}
}
catch (Exception er)
{ MessageBox.Show(er.Message); }
SCOPE_IDENTITY 将 return 最后一个标识值插入同一范围内的标识列中,在此上下文范围内表示您的命令使用的连接。
无论如何,如果仍然需要 MAX 方法,那么可以使用修改后的查询和 SqlCommand.ExecuteScalar 来简化代码,而不是构建 SqlDataReader、填充数据表、尝试解析结果如果
string getMax = @"select COALESCE(MAX(IDCompany), 0) + 1 AS maxPlusOne
from Companii"
using(SqlConnection cnn = new SqlConnection(.....))
using(SqlCommand cmd = new SqlCommand(getMax, cnn))
{
cnn.Open();
int nextCompanyID = Convert.ToInt32(cmd.ExecuteScalar());
}
The COALESCE function检查MAX函数的结果,如果是NULL returns第二个参数(这里是0),那么只要自增1就可以直接从数据库中得到下一个MAX . ExecuteScalar 将只调用 returning maxPlusOne
别名字段
试试这个,我的 ID 格式是 USR001.The 代码将根据数据库中的最后一个 ID 生成自动 ID。如果数据库中的最后一个 id 是 USR001,代码将生成 USR002 并将 id 放入文本框
con.Open();
string sqlQuery = "SELECT TOP 1 kode_user from USERADM order by kode_user desc";
SqlCommand cmd = new SqlCommand(sqlQuery, con);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
string input = dr["kode_user"].ToString();
string angka = input.Substring(input.Length - Math.Min(3, input.Length));
int number = Convert.ToInt32(angka);
number += 1;
string str = number.ToString("D3");
txtKodeUser.Text = "USR" + str;
}
con.Close();