代码之家  ›  专栏  ›  技术社区  ›  Alex Jenter

如何更新数据表中的所有自动增量列?

  •  2
  • Alex Jenter  · 技术社区  · 15 年前

    我有一个带有“id”列的数据表,它是我们的SQL Server 2005数据库中的标识列。此列的autoincrement属性设置为true。我没有用来自数据库的数据填充表,因为我只将它用于插入,所以它从1开始分配伪ID。

    但是在调用tableadapter.update()之后,我希望在该列中包含数据库分配的实际ID。

    出于某种原因,只有第一行被更新,其余的不更新。 此表使用级联数据关系(层次结构)引用自身,并且对第一行的引用也将更新。

    请告诉我如何更新所有的ID。

    事先谢谢!

    插入语句:

    INSERT INTO Components (ComponentId, OrderNo, SerialNo) 
    VALUES (@ComponentId, @OrderNo, @SerialNo) 
    

    这里是components表的模式:

    Id BIGINT PK, 
    ComponentId BIGINT FK, 
    OrderNo int, 
    SerialNo int 
    

    注意,id列的名称是“id”,“componentid”是fk引用列。

    4 回复  |  直到 13 年前
        1
  •  4
  •   takrl cck    13 年前

    这以前真的很容易。您只需将column.autoincrementseed和column.autoincrementstep都设置为“-1”。这样,添加的新行将具有-1、-2等ID。然后,存储的procs或tsql代码将只是:

    UPDATE Table
    SET 
        Col1 = @Col1
        Col2 = @Col2
    WHERE (ID = @ID) -- If this is -1, -2, etc, it won't update
    
    IF (@@ROWCOUNT = 0)
        BEGIN
        INSERT INTO Table(Col1, Col2) VALUES(Col1, Col2)
        SET @ID = SCOPE_IDENTITY();  -- @ID would now change from -1 to 1, 2, 3, etc.
    END
    

    然而,微软在他们的英雄主义智慧改变了这一切更糟的ADO.NET 4.0。我不太确定它什么时候改变了,但是它们在autoincrement列上有一个底层的私有字段,它将该列的当前值存储在里面。所以,假设在数据库中,最后插入的值是“52”,那么,它现在隐藏在autoincrement列中。这导致了现在多用户应用程序的巨大问题,我不能再使用“-1”技巧了,因为它开始从上一个自动递增值倒数。我甚至试图通过反思来改变这一点,但这并没有什么好处。我讨厌微软在ADO.NET中打破了这一点,但他们坚持他们的口号:“不,我们不会修复bug x(这不会真正影响任何用户),但我们将实现一个全新的东西,它会破坏你曾经工作过的所有代码。”

        2
  •  0
  •   KV Prajapati    15 年前

    在执行fill方法之前,使用autoincrement创建一个数据列,

    编辑:

        SqlConnection cn = new SqlConnection(@"Connection_String");
        SqlDataAdapter adp;
        SqlCommandBuilder cb;
        DataTable dt;
    
        private void Form3_Load(object sender, EventArgs e)
        {
            adp= new SqlDataAdapter("select * from temp", cn);
            cb = new SqlCommandBuilder(adp);
            dt = new DataTable();
            dt.Columns.Add("SrNo", typeof(int));
            dt.Columns[0].AutoIncrement = true;
            dt.Columns[0].AutoIncrementSeed = 1;
            dt.Columns[0].AutoIncrementStep = 1;
    
            adp.Fill(dt);
            dataGridView1.DataSource = dt;
        }
        private void button1_Click(object sender, EventArgs e)
        {
            adp.Update(dt);
        }  
    
        3
  •  0
  •   gsharp    15 年前

    必须从SQL返回标识。但我不再确定确切的语法了

    尝试

    INSERT INTO Components (ComponentId, OrderNo, SerialNo) 
    VALUES (@ComponentId, @OrderNo, @SerialNo);
    SET @ComponentId = SCOPE_IDENTITY()
    

    INSERT INTO Components (ComponentId, OrderNo, SerialNo) 
    VALUES (@ComponentId, @OrderNo, @SerialNo);
    SELECT SCOPE_IDENTITY()
    
        4
  •  0
  •   Alex Jenter    15 年前

    问题出在所提到的数据关系中。出于某种原因,由于这种数据关系,“子”行没有插入数据库,并且它们的ID也没有更新为实际的ID,尽管数据表有“刷新数据表”检查(在配置/高级设置中)。

    我已经移除了数据关系,并手工完成了所有工作。以下代码为我提供了诀窍:

    ComponentsTableAdapter cta = new ComponentsTableAdapter();                    
    foreach (UpdaterDataSet.ComponentsRow r in uds.Components.Rows)
    {                    
       long origId = r.Id;
       cta.Update(r);
    
       foreach (UpdaterDataSet.ComponentsRow s in uds.Components.Rows)
       {
          if (s.Id != r.Id && !s.IsComponentIdNull() && s.ComponentId == origId)
             s.ComponentId = r.Id;
       }                 
    }