2013-08-12 60 views
-2

我想插入记录到sql server 2008表中,使用c#asp.net,列值都被声明为“nvarchar”,并且第一列subid是主键。在我的代码中,我检索最后一个coulmn id,递增它并将其用作新记录的子标识符,当我插入一条记录时,它不会按顺序存储,而是存储在中间的某处。因此,下次尝试检索最后一个id列值(尽管我使用“order by”),它给出了现有的值,当它递增时,会给出一个错误,“重复值,不允许”。 这是我的代码来检索值的最后一个ID,并增加它:特定行后插入记录

 SqlCommand myCommand = new SqlCommand("SELECT TOP 1 subid FROM subjects       

     ORDER BY subid DESC", con1);   

      reader = myCommand.ExecuteReader(); 
      if (reader.HasRows == false) 
      { 
       Label4.Text = "1"; 
       reader.Close(); 
      } 
      else 
      { 
       while (reader.Read()) // if can read row from database 
       { 

        id = reader[0].ToString(); 

       } 
       int n = Convert.ToInt32(id); 
       int j = n + 1; 
       Label4.Text = j.ToString(); 

我插入的代码是:

 SqlDataAdapter da = new SqlDataAdapter("SELECT TOP 1 * FROM subjects ORDER BY  
     subid DESC", con); 
     SqlCommandBuilder cb = new SqlCommandBuilder(da); 
     DataSet ds = new DataSet("subjects"); 
     da.Fill(ds, "subjects"); 
     DataRow row = ds.Tables["subjects"].NewRow(); 
     row["subid"] = Label4.Text; 
     row["dept"] = (string)Session["deptmnt"]; 
     row["yr"] = DropDownList2.SelectedValue; 
     row["sem"] = DropDownList3.SelectedValue; 
     row["subname"] = TextBox1.Text; 
     row["subcode"] = TextBox2.Text; 

     ds.Tables["subjects"].Rows.Add(row); 
     da.Update(ds, "subjects"); 

     Label10.Visible = true; 
     con.Close(); 

如何使价值得到插在最后一行,请帮助。 我的subid具有类似“IT10001”,“EC10001”的值,以便根据前两个字母识别部门,这就是为什么我要使用varchar!

+2

这种方法是一个非常可怕的设计 - 您不应该使用“SELECT MAX(..)+ 1”方法来创建新的ID值。这是**不安全**负载下 - 如果多个用户使用此应用程序,而不是稍后您会有重复。 **不要这样做!**在表中使用'INT IDENTITY'列,让SQL Server为您处理ID的唯一性。 –

+0

@marc_s出于兴趣,你每天需要告诉人们多少次? ;-) – Bridge

+0

@Bridge:**方式太多次了!** :-( –

回答

2

在NVarchChar字段上的排序将以字符串形式完成。因此,它将继续与NVARCHAR一起发生。正确的方法是在数据库中将add an integer column设置为auto-increment。这将确保您在添加新行之前不必每次都获得最大值。

+0

,谢谢,但是,我已经创建了许多表,与varchar,所以,现在我不能改变表也作为整数,所以,请给另一种替代方式 – user2605748

+0

不可能与nvarchar。您将不得不吞下药片 – Ehsan

+2

如果您发现不合格的设计,请尽快更换。你以后只会打开更多的痛苦。 – SWeko

2

你有表达式SELECT TOP 1 * FROM subjects ORDER BY subid DESC

如果subid是NVarChar,如您所说,排序是在字符串上进行的,而不是数字。这意味着'10'<'2'。假设你有1000条记录,他们将被勒令:

1 
10 
11 
.. 
19 
100 
101 
... 
1000 
2 
20 
21 
... 
... 
999 

所以,每一次你试图获得最大数量,你会得到字符串“999”回来,因为它是最大的词汇。

最简单的解决方案是将列更改为整数,因为它实际上是一个整数。 如果你绝对肯定不能改变它,那么至少填充零值,所以有“0001”,“0002”,“0010”而不是“1”,“2”,“10”。

此外,使用MAX + 1方法,要求您使用事务处理所有事情,因为并发问题。使用int标识作为主键为您解决了这些问题。