0

设想:

  1. Excel 文件被读取并显示在数据网格中。
  2. 如果 excel 值不同,则必须更新 sql server 中的值。
  3. Sql server 中的表没有主键

在所有这些步骤之后,当我要更新表时,它会抛出错误消息“当传递带有修改行的 DataRow 集合时,更新需要一个有效的 UpdateCommand。”

没有主键。所以我需要使用更新命令。但是更新命令的方式和内容是什么?importdata 是存储 excel 数据的字典。lz帮忙!!!我现在该怎么办?我不知道....

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();    
4

2 回答 2

1

因此,假设我们正在处理一个具有主键的表:

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

第二个建议如下所示:

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();
        }
    }
}
于 2012-11-06T19:49:41.990 回答
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 可以完成其工作。

警告:

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

于 2012-11-06T19:49:37.010 回答