0

こんにちは、私は次のことをしようとしています

  1. テーブル X からすべて削除
  2. 目的の値をテーブル X に挿入します

INSERTコマンドで何かが台無しになるとすべてが削除されるため、T-SQLがそれを達成する方法になると思いました。

しかし、このコードは、データを挿入または削除しない限り何もしません。誰かがこの問題を解決するのを手伝ってくれますか?

spojeni.Open();
SqlTransaction sqlTrans = spojeni.BeginTransaction();
try
{
    string delCmdTxt = "TRUNCATE TABLE PLODINY";
    SqlCommand cmdDel = spojeni.CreateCommand();
    cmdDel.CommandText = delCmdTxt;
    cmdDel.Transaction = sqlTrans;
    cmdDel.ExecuteNonQuery();

    string insert_sql = 
        "INSERT INTO PLODINY(PLODINA,CENAZAQ,MJ)VALUES(@PLODINA,@CENAZAQ,@MJ)";
    SqlCommand sqlcom = spojeni.CreateCommand();
    sqlcom.CommandText = insert_sql;
    sqlcom.Transaction = sqlTrans;

    foreach (DataGridViewRow row in dataGridView1.Rows)
    {
        sqlcom.Parameters.AddWithValue("@PLODINA", row.Cells["PLODINA"].Value);
        sqlcom.Parameters.AddWithValue("@CENAZAQ", row.Cells["CENAZAQ"].Value);
        sqlcom.Parameters.AddWithValue("@MJ", row.Cells["MJ"].Value);

        sqlcom.ExecuteNonQuery();
        sqlcom.Dispose();
    }
    sqlTrans.Commit();
}
catch (System.Data.SqlClient.SqlException)
{
    sqlTrans.Rollback();
}
finally
{
    spojeni.Close();
    spojeni.Dispose();
}
this.Close();
4

3 に答える 3

3

あなたの問題はあなたのforeachループにあります。事前にパラメーターを定義する必要があり、すべての操作が完了するまでコマンド オブジェクトを破棄しないでください。UI 要素であるため、拡張メソッドを使用Whereしてデータ ソースから無効な行を除外することもできます。

string insert_sql = "INSERT INTO PLODINY(PLODINA,CENAZAQ,MJ)VALUES(@PLODINA,@CENAZAQ,@MJ)";
SqlCommand sqlcom = spojeni.CreateCommand();
sqlcom.CommandText = insert_sql;
sqlcom.Transaction = sqlTrans;
sqlcom.Parameters.Add("@PLODINA");
sqlcom.Parameters.Add("@CENAZAQ");
sqlcom.Parameters.Add("@MJ");

// some validation - add what you need.
var validRows = dataGridView1.Rows.Cast<DataGridViewRow>()
  .Where(row => row.Cells["PLODINA"].Value != null);

foreach (DataGridViewRow row in validRows)
{
    sqlcom.Parameters[0].Value = row.Cells["PLODINA"].Value;
    sqlcom.Parameters[1].Value = row.Cells["CENAZAQ"].Value;
    sqlcom.Parameters[2].Value = row.Cells["MJ"].Value;
    sqlcom.ExecuteNonQuery();
}

sqlTrans.Commit();
sqlcom.Dispose();
于 2013-11-09T22:27:17.267 に答える
2

Truncate Table は、テーブルに外部キー制約がない場合にのみ機能します...おそらくそこで失敗し、catch ステートメントでトランザクションをロールバックしています...

Truncate の代わりに Delete From table を試して、それが修正されるかどうかを確認してください...

于 2013-11-09T22:25:45.907 に答える
2

パラメータを完全に間違って実行しています。唯一のことは、catch取得sqlTrans.Rollback();しているエラーが表示されないことです。最初に変更するのは、そのキャッチを作成することです

catch (System.Data.SqlClient.SqlException)
{
    sqlTrans.Rollback();
    throw;
}

これで、エラーが発生することがわかります。

次の問題は、テーブルに外部キー制約TRUNCATE TABLEがある場合に失敗することです。失敗している場合は、単純に置き換えることができます

string delCmdTxt = "delete from PLODINY";
SqlCommand cmdDel = spojeni.CreateCommand();
cmdDel.CommandText = delCmdTxt;
cmdDel.Transaction = sqlTrans;
cmdDel.ExecuteNonQuery();

挿入が機能しない理由については、for ループのインスタンスごとにコマンドを破棄しています。また、毎回パラメーターを再追加しようとしており、そのループを次のように再フォーマットしています。

string insert_sql = "INSERT INTO PLODINY(PLODINA,CENAZAQ,MJ)VALUES(@PLODINA,@CENAZAQ,@MJ)";
using(SqlCommand sqlcom = spojeni.CreateCommand())
{
    sqlcom.CommandText = insert_sql;
    sqlcom.Transaction = sqlTrans;

    sqlcom.Parameters.Add("@PLODINA", SqlDbType.NVarChar); //Replace with whatever the correct datatypes are
    sqlcom.Parameters.Add("@CENAZAQ", SqlDbType.NVarChar);
    sqlcom.Parameters.Add("@MJ", SqlDbType.NVarChar);

    foreach (DataGridViewRow row in dataGridView1.Rows)
    {
        sqlcom.Parameters["@PLODINA"] = row.Cells["PLODINA"].Value;
        sqlcom.Parameters["@CENAZAQ"] = row.Cells["CENAZAQ"].Value;
        sqlcom.Parameters["@MJ"] = row.Cells["MJ"].Value;

        sqlcom.ExecuteNonQuery();    
    }
}
sqlTrans.Commit();

ただし、DataGridView がバインディングを介して DataTable によってサポートされている場合は、代わりに SqlTableAdapter を使用できます。たとえば、データベースからテーブルをロードし、グリッドに表示してから、それをプッシュバックしたいとします。更新された情報。DataTable を使用すると、次のように簡単になります

private string _getDataQuery = "select PLODINA, CENAZAQ, MJ from PLODINY";

public void GetData(DataTable data)
{
    //You do not need to call open here as SqlDataAdapter does it for you internally.
    using(var spojeni = new SqlConnection(GetConnectionString())
    using(var adapter = new SqlDataAdapter(_getDataQuery, spojeni)
    {
        data.Clear();
        adapter.Fill(data);
    }
}

public void UpdateData(DataTable data)
{
    using(var spojeni = new SqlConnection(GetConnectionString())
    using(var adapter = new SqlDataAdapter(_getDataQuery, spojeni)
    using(var commandBuilder = new SqlCommandBuilder(adapter)
    {
        //This may or may not be nessesary for spojeni.BeginTransaction()
        spojeni.Open();

        using(var sqlTrans = spojeni.BeginTransaction())
        {
            adapter.SelectCommand.Transaction = sqlTrans;

            adapter.UpdateCommand = commandBuilder.GetUpdateCommand();
            adapter.UpdateCommand.Transaction = sqlTrans;

            adapter.DeleteCommand = commandBuilder.GetDeleteCommand();
            adapter.DeleteCommand.Transaction = sqlTrans;

            adapter.InsertCommand = commandBuilder.GetInsertCommand()
            adapter.InsertCommand.Transaction = sqlTrans;

            try
            {
                adapter.Update(data);
                sqlTrans.Commit();
            }
            catch
            {
                sqlTrans.Rollback();
                throw;
            }
        }
    }
}
于 2013-11-09T22:30:32.697 に答える