更改行后更新数据集

时间:2012-11-06 19:23:36

标签: c# sql excel

情景:

  1. 读取Excel文件并在datagrid中显示。
  2. 如果Excel值不同,则必须更新sql server中的值。
  3. Sql server中的表没有主键
  4. 在完成所有这些步骤之后,当我要更新表时,它会抛出错误“在传递带有已修改行的DataRow集合时,Update需要有效的UpdateCommand”。

    没有主键。所以我需要使用update命令。如何以及更新命令中的内容? importdata是存储来自excel的数据的字典。 PLZ帮助!!!我现在应该怎么做?我不知道......

    foreach (DataColumn column in ds.Tables[0].Columns)
    {
        string fieldName = column.ColumnName;
        string fieldNameValueE = string.Empty;
        if (importdata.ContainsKey(fieldName))
        {
            fieldNameValueE = importdata[fieldName];
            foreach (DataRow dr in ds.Tables[0].Rows)
            {
                string fieldNameValueD = dr[fieldName].ToString();
                if (fieldNameValueD != fieldNameValueE)
                {
                    dr[fieldName] = fieldNameValueE;
    
                }
            }
    
        }
    
    }
    
    da.Update(ds);
    connection.Close();    
    

2 个答案:

答案 0 :(得分:0)

使用SqlCommandBuilder。

设置DataAdapter后,初始化命令构建器。 然后使用SqlCommandBuilder更新功能。

SqlCommandBuilder cb = new SqlCommandBuilder(da);

//Do your other work updating the data

cb.DataAdapter.Update(ds);

这应该可以做到!

修改:

正如BigM所指出的那样,你的表需要有一个主键才能使SqlCommandBuilder工作。但是,如果您无法修改实际的SQL表并将其中一个字段标记为主键,并且know其中一个字段是唯一的,则可以将一个主键添加到DataSet表中,如下所示:

DataColumn[] pk1 = new DataColumn[1];
pk1[0] = ds.Tables["TableName"].Columns[0];
ds.Tables["TableName"].PrimaryKey = pk1;

这为您的“内存”表提供了一个主键,以便SqlCommandBuilder可以完成其工作。

警告:

您必须确保标记为主键的列中的值实际上是唯一的。

答案 1 :(得分:0)

所以,假设我们正在处理一个有主键的表:

CREATE TABLE TableA
{
    FieldA INT PRIMARY KEY IDENTITY(1, 1),
    FieldB VARCHAR(256) NULL,
    FieldC VARCHAR(256) NOT NULL,
}

如果你要使用SqlCommandBuilder(你不能因为你没有主键而使用它),它会建立一个类似这样的语句:

UPDATE TableA
    SET FieldB = @p1,
        FieldC = @p2
WHERE (FieldA = @p3 AND
    ((FieldB IS NULL AND @p4 IS NULL) OR (FieldB = @p5)) AND
    FieldC = @p6)

所以,你需要构建一个UPDATE语句,它与它们的方式非常相似。但是你需要记住的一件事是它不仅仅是声明,你还必须将所有参数添加到你构建的命令中 - 这将变得非常麻烦。

所以,我有两条建议:

  1. 在桌子上制作主键。
  2. 在循环的每次迭代中发出ExecuteNonQuery
  3. 第二条建议如下:

    foreach (DataColumn column in ds.Tables[0].Columns)
    {
        string fieldName = column.ColumnName;
        string fieldNameValueE = string.Empty;
        if (importdata.ContainsKey(fieldName))
        {
            fieldNameValueE = importdata[fieldName];
            foreach (DataRow dr in ds.Tables[0].Rows)
            {
                string fieldNameValueD = dr[fieldName].ToString();
                if (fieldNameValueD != fieldNameValueE)
                {
                    dr[fieldName] = fieldNameValueE;
                }
    
                var cmd = new SqlCommand(string.Format(
                    "UPDATE importdata SET {0} = {1} WHERE fielda = @fielda AND fieldb = @fieldb ...",
                    fieldName, fieldNameValueE), connectionObject);
                cmd.Parameters.AddWithValue(@fielda, dr["fielda", DataRowVersion.Original]);
                cmd.Parameters.AddWithValue(@fieldb, dr["fieldb", DataRowVersion.Original]);
    
                cmd.ExecuteNonQuery();
            }
        }
    }