Marek
Marek

Reputation: 3575

T-SQL Delete * from table then insert into table

Hello I'm trying to do following

  1. Delete all from table X
  2. insert desired values into table X

I thought then T-SQL would be way to achieve that because when something messes up in the INSERT command then everything will be deleted.

But this code does nothing it doesn't insert or delete the data. May someone help me to fix this issue?

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

Upvotes: 0

Views: 1024

Answers (3)

Scott Chamberlain
Scott Chamberlain

Reputation: 127553

You are doing your parameters totally wrong, because the only thing in your catch is the sqlTrans.Rollback(); you never see the errors you are getting, the first thing I would change is make that catch

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

so you can now see the errors happen.

The next issue is if the table has any foreign key constraints your TRUNCATE TABLE will fail, if it is failing you can simply replace it with

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

As to why your inserts are not working, you are disposing the command every instance of the for loop, you are also trying to re-add the parameters every time, reformat that loop to the following

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

However your code can be made even better, if your DataGridView was backed by a DataTable via binding you could use a SqlTableAdapter instead, Lets say you load the table from the database, display it on the grid, and then you want to push back the updated information. With a DataTable it would be as simple as

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;
            }
        }
    }
}

Upvotes: 2

Daniel Gimenez
Daniel Gimenez

Reputation: 20494

Your problem is in your foreach loop. You need to define your parameters before hand, and do not dispose the command object until you're all done with it. You can also use the Where extension method to filter out any invalid rows from your data source since its a UI element.

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

Upvotes: 3

Nathan Prather
Nathan Prather

Reputation: 2106

Truncate Table only works if the table has not foreign key constraints... it's probably failing there and then rolling back the transaction in the catch statement...

Instead of Truncate try Delete From table and see if that fixes it...

Upvotes: 2

Related Questions