0

シナリオ:

  1. Excelファイルを読み込んでデータグリッドに表示します。
  2. Excel の値が異なる場合は、SQL サーバーの値を更新する必要があります。
  3. SQL サーバーのテーブルに主キーがありません

これらすべての手順の後、テーブルを更新しようとすると、「更新には、変更された行を含む DataRow コレクションを渡すときに有効な UpdateCommand が必要です」というエラーがスローされます。

主キーはありません。したがって、更新コマンドを使用する必要があります。しかし、更新コマンドにはどのように、そして何が含まれるでしょうか? 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();    
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そのため、彼らが行っている方法と非常によく似たステートメントを作成する必要があります。ただし、覚えておく必要があるのは、ステートメントだけでなく、作成するコマンドにすべてのパラメーターを追加する必要があることです。これはかなり面倒になります。

そこで、次の 2 つのお勧めがあります。

  1. テーブルに主キーを作成します。
  2. ExecuteNonQueryループの反復ごとに を発行します。

2 番目の推奨事項は次のようになります。

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 テーブルを変更できず、フィールドの 1 つを主キーとしてマークできず、フィールドのknow1 つが一意である場合は、次のように 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 に答える