2015-05-03 22 views
0

我使用此代码从数据库表中选择maxID,并且每次我想添加新记录时,自动生成的ID不是最后一个一个+1。当试图向数据库添加新记录时,在C#中自动生成和自动增量ID

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); } 
    } 

从那里做出选择表,如下所示:

IDCompany Name Address City RegNo 
1   A  Street NY 123 

每次我想添加一个新的记录,自动生成的ID是这样的:11,111,1111。它取最后一个ID并在其旁添加另一个1。我错过了什么?

+3

您是否知道SQL Server有IDENTITY列,这些列可以为您生成自动增量值,你正试图用MAX函数来模拟? (如果您拥有多个并发用户,则为安全的失败方式) – Steve

+2

除了@Steve提及的内容之外,如果您有多个用户同时使用系统,则会失败,因为它们的两个客户端实例可以轻松生成相同的ID。 –

+0

@Steve - 我知道IDENTITY属性,但我不知道如何将它链接到我的应用程序,所以我选择了这种方式.. – cdrrr

回答

2

有趣的是,注意

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]到一个字符串a对字符串的末尾加+1而不是整数值。尝试

(int.Parse(idmax.Rows[0][0].ToString()) + 1).ToString(); } 

注意idmax.Rows[0][0]应该已经有一个整数(如在评论中指出)。如果是这样的话,你可以简化为

(idmax.Rows[0][0] + 1).ToString(); } 
+1

为什么'toInt(toString(x))'呢? – user2864740

+0

@ user2864740:公平点。我没有对idmax.Rows [0] [0]中的实际内容做出假设,并试图尽量保持与原始代码接近,只是突出显示了重大变化。但是那里已经有了一个int。我会加上我的答案来指出这一点。 –

2

idmax.Rows[0][0].ToString() + 1产生string而不是int

您可以尝试

txtID.Text = (Convert.ToInt32(idmax.Rows[0][0]) + 1).ToString(); 
0

试试这个片断:

转换您StringIntString+运营商将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); } 
1

我只是补充一点,因为它似乎没有关心海报发布的代码的弱点。 如果您想要查找将分配给ID列的下一个自动增量值,则首先MAX函数不可靠。并发性可能会对使用MAX的任何模式造成严重破坏。假设另一个用户已经为其自己的INSERT操作检索了MAX,然后根据两台计算机的相对速度,您或其他用户将为IDCompany字段插入一个重复值。

做这个共同的任务,唯一正确的方法是使用IDENTITY属性为列IDCompany,当你需要插入一个新的记录,你应该写这样的事情

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将返回最后标识值插入同一范围内的标识列中,并且在此上下文范围内表示您的命令使用的连接。

在任何情况下,如果仍需要的MAX方法然后代码可以用一个修改的查询和SqlCommand.ExecuteScalar而不是修建一个SqlDataReader的,填充数据表,试图解析与IFS结果能够简化很多

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,则返回第二个参数(这里是0),然后只加1以直接从数据库中获取下一个MAX。 ExecuteScalar将执行只返回maxPlusOne别名字段的呼叫

+1

只是不明白为什么这不是明显的答案。 – Paul

0

尝试这一个,我的ID格式为USR001。该代码将根据数据库中的最后一个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(); 
相关问题