update table in database from datatable - c#

I load data from database table like this...
using (view_adapter = new SqlDataAdapter("select * from TVServiceProvider", connection_string))
{
using (dt = new DataTable())
{
view_adapter.Fill(dt);
for (int i = 0; i < dt.Columns.Count; i++)
{
if (dt.Columns[i].ColumnName.Substring(0, 2).Equals("id"))
dt.Columns[i].ReadOnly = false;
}
bs.DataSource = dt;
}
}
Where SqlDataAdapter view_adapter and DataTable dt. To apply changes to database I've created method
void View_Adapter_Click(object sender, EventArgs e)
{
try
{
view_adapter.Update(dt);
dt.AcceptChanges();
}
catch (Exception exc)
{
this.radLabelElement1.Text = exc.Message;
}
}
But when I click the button I've got an exception. It requires update command. Where and what command I should use?

You must create UpdateCommand and DeleteCommand for you view_adapter.
EDIT:
The code must look like this:
SqlDataAdapter view_adapter = new SqlDataAdapter();
view_adapter .SelectCommand = new SqlCommand(queryString, connection);
view_adapter .UpdateCommand = new SqlCommand(updateCommadString, connection);
view_adapter .DeleteCommand = new SqlCommand(deleteCommadString, connection);
using (SqlConnection connection = new SqlConnection(connectionString))
{
view_adapter.Fill(dt);
return dt;
}

Well, something is wrong or not clear in your code.
The view_adapter variable is initialized within a using block statement.
Thus, when exiting from the using block, the view_adatpter will be disposed by the framework and unusable in the click event. (like you have never called new to initialize it).
I suspect that you have another problem here. Using statement
A part from this, to automatically create the UpdateCommand, InsertCommand and DeleteCommand required to perform CRUD operations with a DataAdapter you could use a SqlCommandBuilder.
(This is possible only if you use one table in the select statement and that table has a primary key defined)
So to summarize everything:
string queryString = "select * from TVServiceProvider";
view_adapter = new SqlDataAdapter(queryString, connection_string);
SqlCommandBuilder builder = new SqlCommandBuilder(view_adapter)
builder.GetUpdateCommand(); // Force the building of commands
view_adapter.Fill(dt);
then your click event should works as is now.

This code is not related to yours, but may help you, If you give it a look. I got it from MSDN
public static SqlDataAdapter CreateCustomerAdapter(
SqlConnection connection)
{
SqlDataAdapter adapter = new SqlDataAdapter();
// Create the SelectCommand.
SqlCommand command = new SqlCommand("SELECT * FROM Customers " +
"WHERE Country = #Country AND City = #City", connection);
// Add the parameters for the SelectCommand.
command.Parameters.Add("#Country", SqlDbType.NVarChar, 15);
command.Parameters.Add("#City", SqlDbType.NVarChar, 15);
adapter.SelectCommand = command;
// Create the InsertCommand.
command = new SqlCommand(
"INSERT INTO Customers (CustomerID, CompanyName) " +
"VALUES (#CustomerID, #CompanyName)", connection);
// Add the parameters for the InsertCommand.
command.Parameters.Add("#CustomerID", SqlDbType.NChar, 5, "CustomerID");
command.Parameters.Add("#CompanyName", SqlDbType.NVarChar, 40, "CompanyName");
adapter.InsertCommand = command;
// Create the UpdateCommand.
command = new SqlCommand(
"UPDATE Customers SET CustomerID = #CustomerID, CompanyName = #CompanyName " +
"WHERE CustomerID = #oldCustomerID", connection);
// Add the parameters for the UpdateCommand.
command.Parameters.Add("#CustomerID", SqlDbType.NChar, 5, "CustomerID");
command.Parameters.Add("#CompanyName", SqlDbType.NVarChar, 40, "CompanyName");
SqlParameter parameter = command.Parameters.Add(
"#oldCustomerID", SqlDbType.NChar, 5, "CustomerID");
parameter.SourceVersion = DataRowVersion.Original;
adapter.UpdateCommand = command;
// Create the DeleteCommand.
command = new SqlCommand(
"DELETE FROM Customers WHERE CustomerID = #CustomerID", connection);
// Add the parameters for the DeleteCommand.
parameter = command.Parameters.Add(
"#CustomerID", SqlDbType.NChar, 5, "CustomerID");
parameter.SourceVersion = DataRowVersion.Original;
adapter.DeleteCommand = command;
return adapter;
}

What actually worked for me from Steve and Hamlet's suggestions is the following. I had one hiccup because I tried to do an accept changes on my rows and table before doing the view adapter update. The accept changes in only needed to save the changes to the datatable before reusing the datatable for displaying in a gridview or other operations.
SqlDataAdapter viewAdapter = new SqlDataAdapter("Select * From Users", DBConn);
SqlCommandBuilder builder = new SqlCommandBuilder(viewAdapter);
viewAdapter.UpdateCommand = builder.GetUpdateCommand();
DataTable Users = new DataTable();
viewAdapter.Fill(Users);
foreach (DataRow user in Users.Rows)
{
foreach (DataColumn c in Users.Columns)
{
Console.WriteLine(c.ColumnName);
if (c.DataType != typeof(DateTime))
{
// Clean up empty space around field entries
user[c.ColumnName] = user[c.ColumnName].ToString().Trim();
}
}
// user.AcceptChanges();
// Do not do an accept changes for either the table or the row before your ViewAdapter Update.
// It will appear as though you do not have changes to push.
}
// Users.AcceptChanges();
viewAdapter.Update(Users);

Related

Changes not saving to database using SqlDataAdapter

I'm stuck with my changes not getting saved to the SQL Server database.
I can read the database properly, and when calling RefreshGrid() that refreshes from the database, the gridview updates correctly. But not when restarting the program or checking the actual database, then the changes are gone.
I would normally use Entity Framework for this, but sometimes one needs to learn other ways.
private string conString = ConfigurationManager.ConnectionStrings["RewardsConnectionString"].ConnectionString;
private RewardsDS rewardsDset = new RewardsDS();
private SqlDataAdapter CreateDataAdapter(SqlConnection conn)
{
// Build the selection query.
SqlDataAdapter rewardsAdapter = new SqlDataAdapter();
SqlCommand selectCommand = new SqlCommand("SELECT * FROM Purchases", conn);
rewardsAdapter.SelectCommand = selectCommand;
// Build the insertion query
SqlCommand insertCommand = new SqlCommand(
#"INSERT INTO Purchases (PurchaseDate, Amount, CustomerId)
VALUES (#PurchaseDate, #Amount, #CustomerId)", conn);
insertCommand.Parameters.Add("#PurchaseDate", SqlDbType.DateTime, 0, "PurchaseDate"); // Not sure about this zero ...
insertCommand.Parameters.Add("#Amount", SqlDbType.Decimal, 0, "Amount");
insertCommand.Parameters.Add("#CustomerId", SqlDbType.Int, 0, "CustomerId");
rewardsAdapter.InsertCommand = insertCommand;
// Build the update query
SqlCommand updateCommand = new SqlCommand(
#"UPDATE Purchases SET Amount = #Amount, PurchaseDate = #PurchaseDate WHERE PurchaseId = #PurchaseId", conn);
updateCommand.Parameters.Add("#Amount", SqlDbType.Decimal, 0, "Amount");
updateCommand.Parameters.Add("#PurchaseDate", SqlDbType.DateTime, 0, "PurchaseDate");
SqlParameter param = updateCommand.Parameters.Add("#PurchaseId", SqlDbType.Int, 0, "PurchaseId");
param.SourceVersion = DataRowVersion.Original;
rewardsAdapter.UpdateCommand = updateCommand;
// Build the delete query
SqlCommand deleteCommand = new SqlCommand(
"DELETE FROM Purchases WHERE PurchaseId = #PurchaseId", conn);
param = deleteCommand.Parameters.Add("#Id", SqlDbType.Int, 0, "PurchaseId");
param.SourceVersion = DataRowVersion.Original;
rewardsAdapter.DeleteCommand = deleteCommand;
return rewardsAdapter;
}
// Gets changes and saves them to the database.
private void SaveChanges()
{
using (SqlConnection conn = new SqlConnection(conString))
{
var fadapter = CreateDataAdapter(conn);
conn.Open();
DataSet changes = rewardsDset.GetChanges();
try
{
fadapter.Update(changes, "Purchases");
}
catch (Exception ex)
{
MessageBox.Show("There are no updates to be saved");
}
conn.Close();
rewardsDset.AcceptChanges();
}
}
// Refresh the dataGridView from the database
private void RefreshGrid()
{
rewardsDset.Clear();
using (SqlConnection conn = new SqlConnection(conString))
{
conn.Open();
SqlDataAdapter myAdapter = new SqlDataAdapter("SELECT * FROM Purchases", conn);
myAdapter.Fill(rewardsDset, "Purchases");
conn.Close();
dataGridView1.DataSource = null;
this.dataGridView1.DataSource = rewardsDset.Tables["Purchases"];
}
}
You simply have to execute the queries:
rewardsAdapter.InsertCommand.ExecuteNonQuery();
I will start by apologizing for wasting anyone's time. Finally found what was causing this error and it was far more basic than I thought and not at all where I've been trying to look for solutions.
I've made an embarrassing mistake regarding the connection string, but if someone repeats my mistake this was it:
I've been using the connection string to the DataSet, and not to the actual database ...
Adding the proper connection string certainly solved my problem, and was of course impossible for anyone to see with only the code I posted above.

How to Use an Update Statement in SQLDataAdapter

I am trying to run an update statement after i built my sqldataadapter. I have column called INIT_PHASE in my table and if the INIT_PHASE is null or there is no data then i would like to set it to 1. I have tried but i can't seem to get it right the update statement. Pls. help. here is my code:
string ID = ddlPractice.SelectedValue;
string TYPE = DDL_TYPE.SelectedValue;
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["myConnection"].ConnectionString);
SqlDataAdapter da = new SqlDataAdapter(#"select SET_SK, UNIT_NM, TYPE, INIT_PHASE FROM myTable WHERE UNIT_NM =#ID AND TYPE = #TYPE", con);
DataTable dtSETS = new DataTable();
da.SelectCommand.Parameters.AddWithValue("#ID", (ID));
da.SelectCommand.Parameters.AddWithValue("#TYPE", (TYPE));
da.Fill(dtSETS);
if (dtSETS.Rows.Count > 0)
{
DataRow dtSETS_row = dtSETS.Rows[0];
long SET_SK = dtSETS_row.Field<long>("SET_SK");
if (dtSETS_row.Field<string>("INIT_PHASE") == null)
{
//run update command here
update myTable set INIT_PHASE = 1;
}
}
One approach here would be to use the SqlCommandBuilder to build the UPDATE statement:
string ID = ddlPractice.SelectedValue;
string TYPE = DDL_TYPE.SelectedValue;
SqlConnection con = new SqlConnection(
ConfigurationManager.ConnectionStrings["myConnection"].ConnectionString);
SqlDataAdapter da = new SqlDataAdapter(
#"select SET_SK, UNIT_NM, TYPE, INIT_PHASE FROM myTable WHERE UNIT_NM =#ID AND TYPE = #TYPE",
con);
DataTable dtSETS = new DataTable();
da.SelectCommand.Parameters.AddWithValue("#ID", (ID));
da.SelectCommand.Parameters.AddWithValue("#TYPE", (TYPE));
da.Fill(dtSETS);
SqlCommandBuilder builder = new SqlCommandBuilder(da);
da.UpdateCommand = builder.GetUpdateCommand();
if (dtSETS.Rows.Count > 0)
{
DataRow dtSETS_row = dtSETS.Rows[0];
long SET_SK = dtSETS_row.Field<long>("SET_SK");
if (dtSETS_row.Field<string>("INIT_PHASE") == null)
{
dtSETS_row["INIT_PHASE"] = 1;
}
}
da.Update(dtSETS);
Take note to the following lines of code. Here we are building the update command:
SqlCommandBuilder builder = new SqlCommandBuilder(da);
da.UpdateCommand = builder.GetUpdateCommand();
here we are literally modifying the DataRow so that it's RowState is changed to Modified:
dtSETS_row["INIT_PHASE"] = 1;
and then finally, here we are sending updates to the database with the Update method on the SqlDataAdapter:
da.Update(dtSETS);
What this is going to do is only send updates for the rows with a RowState of Modified.
NOTE: each of the ADO.NET objects should be wrapped in a using. Refactor your code to match this type of template:
using (SqlConnection con = new SqlConnection(...))
{
using (SqlDataAdapter da = new SqlDataAdapter(...))
{
}
}
If I understand correctly, you could execute directly a command to update just this field
if (dtSETS_row.Field<string>("INIT_PHASE") == null)
{
SqlCommand cmd = new SqlCommand(#"UPDATE myTable set INIT_PHASE = 1 " +
"WHERE UNIT_NM =#ID AND TYPE = #TYPE", con);
cmd.Parameters.AddWithValue("#ID", (ID));
cmd.Parameters.AddWithValue("#TYPE", (TYPE));
cmd.ExecuteNonQuery();
}
You need to open the connection though both for the SqlDataAdapter and for the following command
You will have to use SqlCommandBuilder class for updating data in disconnected mode. ie) DataSet and Data Adapters.

SqlAdapter.Update() method perform insertion instead of updation

I used SqlAdapter.Update() method to update the rows in a table.
For that I created Datatable and add values to that datatable.
DataTable dtTable = new DataTable("Product");
SqlConnection myLocalConnection = new SqlConnection(_ConnectionString);
SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter("Select * from " + dtTable.TableName, myLocalConnection);
SqlCommandBuilder mySqlCommandBuilder = new SqlCommandBuilder(mySqlDataAdapter);
mySqlDataAdapter.Update(dtTable);
When I using this command it insert new rows in the database rather than updating the existing rows. Why does this happen?
I think what is happening here is (As per your given code) your dataadapter is unable to recognize rows in your datatable it is nowhere related to your datatable here, So as a guess try to fill your datatable via dataadapter then modify your datatable and update it.
DataTable dtTable = new DataTable();
SqlConnection myLocalConnection = new SqlConnection(_ConnectionString);
SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter("Select * from " +
dtTable.TableName, myLocalConnection);
SqlCommandBuilder builder= new SqlCommandBuilder(mySqlDataAdapter);
mySqlDataAdapter.Fill(dtTable,"Products" )
// Code to modify your datatable
mySqlDataAdapter.UpdateCommand = builder.GetUpdateCommand();
mySqlDataAdapter.Update(dtTable);
-- Hope it helps .
This is just an idea and not the solution...
// update command to update database table.
string strUpdateCommand =
"Update Students set Name = #Name, Gender = #Gender, Total = #Total where ID = #ID";
// create an instance of SqlCommand using the update command created above.
SqlCommand updateCommand = new SqlCommand(strUpdateCommand, con);
// specify the paramaters of the update command.
updateCommand.Parameters.Add("#Name", SqlDbType.NVarChar, 50, "Name");
updateCommand.Parameters.Add("#Gender", SqlDbType.NVarChar, 20, "Gender");
updateCommand.Parameters.Add("#Total", SqlDbType.Int, 0, "Total");
updateCommand.Parameters.Add("#ID", SqlDbType.Int, 0, "ID");
// associate update command with SqlDataAdapter instance.
dataAdapter.UpdateCommand = updateCommand;

Basic method to export cells values from GridView to SQL table

I need to read i little course about how to export a gridView in DevExpress to a SQL table..
like the values First Name, Father Name, Last Name to a table Employee and i have many rows..
how can I loop into every row and send data to the database..
Thx in advance
I tried this code:
string sql = #"INSERT INTO Emp (#FName, #MName,#LName, #Code, #TaxNb, #SSN, #EmploymentType, #DOB, #MarStat, #RegNum, #BadgeNum, #HireDate, #TaxSince, #HireSince, #ArEmpName, #ArFatherName, #ArLastName, ArPayUnit)";
DataTable table = new DataTable();
try
{
SqlConnection connection = new SqlConnection(#"workstation id = PC-PC; user id=sa;Password=sapassword; data source=pc-pc; persist security info=True;initial catalog=CleanPayrollTest2");
SqlCommand command = new SqlCommand(sql, connection);
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.InsertCommand = command;
connection.Open();
// for (int i =0; i< gridView3.RowCount; i++)
//{
//command.Parameters.Add(#FirstName, gridView3.GetRowCellValue(i,gridView3.Columns));
//adapter.InsertCommand.ExecuteNonQuery();
//}
SqlParameter[] MyParams = new SqlParameter[28];
MyParams[0] = new SqlParameter("#FName", SqlDbType.VarChar, 20);
MyParams[0].SourceColumn = FirstName;
command.Parameters.Add("#FName", SqlDbType.VarChar, 20);
MyParams[1] = new SqlParameter("#MName", SqlDbType.VarChar, 20);
MyParams[1].SourceColumn = FatherName;
MyParams[2] = new SqlParameter("#LName", SqlDbType.VarChar, 20);
MyParams[2].SourceColumn = LastName;
From SqlDataAdapter Class:
The SqlDataAdapter, serves as a bridge between a DataSet and SQL
Server for retrieving and saving data.
In the scenario you described, there is no such need for a "bridge". You just use a SqlCommand, add the collection of SqlParameter to it, and then call ExecuteNonQuery() to perform the insert.
using(SqlConnection connection = new SqlConnection(#"workstation id = PC-PC; user id=sa;Password=sapassword; data source=pc-pc; persist security info=True;initial catalog=CleanPayrollTest2"))
{
using(SqlCommand command = new SqlCommand(sql, connection))
{
try
{
connection.Open();
for (int i =0; i< gridView3.RowCount; i++)
{
SqlParameter parameter = new SqlParameter();
// TODO: handle name accordingly (MName, LName etc.)
parameter.ParameterName = "#FName";
// TODO: handle type accordingly
parameter.SqlDbType = SqlDbType.NVarChar;
parameter.Direction = ParameterDirection.Input;
// TODO: use the field name accordingly
parameter.Value = Convert.ToString(gridView3.GetRowCellValue(i, "FieldName"));
// add the parameter to the command
command.Parameters.Add(parameter);
}
command.ExecuteNonQuery();
}
catch(Exception)
{
// TODO: handle the exception
}
}
}
Remark: you should dispose your SQL related objects in the code - a convenient way to do that is to use using statements.

SQL DataTable Update?

I'm not sure, but I think I may have taken a wrong path here. I am trying to update my customer table on my SQL Server. I Connected with a SQLDatareader and then loaded that into my Datatable. I have made all the changes I wanted and now I can't figure out how to get the changes back up. I thought that the "myDataTable.AcceptChanges();" would trigger that to happen but it doesn't.
SqlConnection myConnection = new SqlConnection();
SqlCommand myCommand;
DataTable myDataTable;
SqlDataReader myReader;
myCommand = new SqlCommand();
myCommand.CommandText = " SELECT * FROM customer";
myCommand.CommandType = CommandType.Text;
myCommand.Connection = myConnection;
myCommand.Connection.Open();
myReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection);
myDataTable = new DataTable();
myDataTable.Load(myReader);
// Make Data changes here
myDataTable.AcceptChanges();
MyDataTable.Dispose();
MyCommand.Dispose();
MyConnection.Dispose();
You can use a TableAdapter to commit your changes back to the database. Check out this link for details.
TableAdapter.Update()
In such case you need to use a DataAdapter which has an Update property that takes your Update Query Command.
Even you can use Command Builder and then get the UpdateCommand from CommandBuilder.
Sample Code from MSDN
SqlDataAdapter catDA = new SqlDataAdapter("SELECT CategoryID, CategoryName FROM Categories", nwindConn);
catDA.UpdateCommand = new SqlCommand("UPDATE Categories SET CategoryName = #CategoryName " +
"WHERE CategoryID = #CategoryID" , nwindConn);
catDA.UpdateCommand.Parameters.Add("#CategoryName", SqlDbType.NVarChar, 15, "CategoryName");
SqlParameter workParm = catDA.UpdateCommand.Parameters.Add("#CategoryID", SqlDbType.Int);
workParm.SourceColumn = "CategoryID";
workParm.SourceVersion = DataRowVersion.Original;
DataSet catDS = new DataSet();
catDA.Fill(catDS, "Categories");
DataRow cRow = catDS.Tables["Categories"].Rows[0];
cRow["CategoryName"] = "New Category";
catDA.Update(catDS);
MSDN Link

Categories

Resources