从表中删除T-SQL然后插入到表中

时间:2013-11-09 22:12:44

标签: c# sql sql-server tsql

您好我正在尝试执行以下操作

  1. 从表格X中删除全部
  2. 将所需的值插入表X
  3. 我认为T-SQL可以实现这一点,因为当INSERT命令出现问题时,一切都将被删除。

    但是这段代码没有做任何事情,它没有插入或删除数据。有人可以帮我解决这个问题吗?

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

3 个答案:

答案 0 :(得分:3)

您的问题出在foreach循环中。您需要事先定义参数,并且在完成所有操作之前不要处置命令对象。您还可以使用Where扩展方法从数据源中删除任何无效行,因为它是一个UI元素。

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

答案 1 :(得分:2)

截断表仅在表没有外键约束时才有效...它可能在那里失败然后在catch语句中回滚事务...

而不是Truncate尝试从表中删除并查看是否修复了它...

答案 2 :(得分: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通过binding支持你可以使用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;
            }
        }
    }
}