I have a table which has some 100-200 records.
I have fetch those records into a dataset.
Now i am looping through all the records using foreach
dataset.Tables[0].AsEnumerable()
I want to update a column for each record in the loop. How can i do this. Using the same dataset.
I'm Assumng your using a Data Adapter to Fill the Data Set, with a Select Command?
To edit the data in your Data Table and save changes back to your database you will require an Update Command for you Data Adapter. Something like this :-
SQLConnection connector = new SQLConnection(#"Your connection string");
SQLAdaptor Adaptor = new SQLAdaptor();
Updatecmd = new sqlDbCommand("UPDATE YOURTABLE SET FIELD1= #FIELD1, FIELD2= #FIELD2 WHERE ID = #ID", connector);
You will also need to Add Parameters for the fields :-
Updatecmd.Parameters.Add("#FIELD1", SQLDbType.VarCHar, 8, "FIELD1");
Updatecmd.Parameters.Add("#FIELD2", SQLDbType.VarCHar, 8, "FIELD2");
var param = Updatecmd.Parameters.Add("#ID", SqlDbType.Interger, 6, "ID");
param.SourceVersion = DataRowVersion.Original;
Once you have created an Update Command with the correct SQL statement, and added the parameters, you need to assign this as the Insert Command for you Data Adapter :-
Adaptor.UpdateCommand = Updatecmd;
You will need to read up on doing this yourself, go through some examples, this is a rough guide.
The next step is to Enumerate through your data table, you dont need LINQ, you can do this :-
foreach(DataRow row in Dataset.Tables[0].Rows)
{
row["YourColumn"] = YOURVALUE;
}
One this is finished, you need to call the Update() method of yout Data Adapter like so :-
DataAdapter.Update(dataset.Tables[0]);
What happens here, is the Data Adapter calls the Update command and saves the changes back to the database.
Please Note, If wish to ADD new rows to the Database, you will require am INSERT Command for the Data Adapter.
This is very roughly coded out, from the top of my head, so the syntax may be slightly out. But will hopefully help.
You should use original DataAdapter (adapter in code below) that was used to fill DataSet and call Update method, you will need CommandBuilder also, it depends what DB you are using, here is the example for SQL server :
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
adapter.UpdateCommand = builder.GetUpdateCommand();
adapter.Update(dataset);
dataset.AcceptChanges();
Here is the good example :
http://support.microsoft.com/kb/307587
The steps would be something like:
- create a new DataColumn[^]
- add it to the data table's Columns[^] collection
- Create a DataRow [^] for example using NewRow[^]
- Modify the values of the row as per needed using Item[^] indexer
- add the row to Rows[^] collection
- after succesful modifications AcceptChanges[^]
Like this:
DataTable table = new DataTable();
table.Columns.Add("ID", typeof(int));
table.Columns.Add("ProductName");
table.Rows.Add(1, "Chai");
table.Rows.Add(2, "Queso Cabrales");
table.Rows.Add(3, "Tofu");
EnumerableRowCollection<DataRow> Rows = table.AsEnumerable();
foreach (DataRow Row in Rows)
Row["ID"] = (int)Row["ID"] * 2;
Add the column like below.
dataset.Tables[0].Columns.Add(new DataColumn ("columnname"));
Update the columns values like below.
for (int i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
{
dataset.Tables[0].Rows[i]["columnname"] = "new value here";
}
Update Database
dataset.AcceptChanges();
Related
Given a DataTable loaded with some data how can it be reused to perform multiple inserts into different SQL Server database tables using different SqlDataAdapter.Update() methods?
After using the DataTable to insert records into table 1, a different SqlDataAdapter will not insert data into table 2 and Update() method always returns 0 without throwing an exception.
I tried using the Copy() and RejectChanges() methods of the DataTable but it never inserts data into table 2.
Some code:
var dataAdapter1 = new SqlDataAdapter
{
UpdateBatchSize = updateBatchSize,
InsertCommand = new SqlCommand(insertCommand1, dbConnection)
{
UpdatedRowSource = UpdateRowSource.None
}
};
dataAdapter1 .InsertCommand.Parameters.Add("#Id", SqlDbType.Int, 0, "Id");
dbConnection.Open();
dataAdapter1 .Update(dtSomeDataTable);
// This inserts data into table 1.
var dataAdapter2 = new SqlDataAdapter
{
UpdateBatchSize = updateBatchSize,
InsertCommand = new SqlCommand(insertCommand2, dbConnection)
{
UpdatedRowSource = UpdateRowSource.None
}
};
var count = dataAdapter2.Update(dtSomeDataTable);
//This does not insert any records (or throws an exception) and variable count is always 0;
Take a look at this MSDN post to understand the concept of DataRow.RowState: https://msdn.microsoft.com/en-us/library/ww3k31w0(v=vs.110).aspx
When you call Update on the first SqlAdapter, all rows are marked as Unchanged and subsequent Update calls won't consider them anymore.
You could try "touching" each row by reading a value from one of the columns and setting that same value. Maybe that will cause the RowState to switch to Modified so that the second Update operation acts on all rows again.
Maybe try calling SetAdded on each DataRow, before the 2nd call to Update ?
https://msdn.microsoft.com/en-us/library/system.data.datarow.setadded%28v=vs.110%29.aspx
Resolved by keeping the original DataTable unchanged and working on copies for each required update created using the DataTable.Copy() method... If a better answer is posted I'll accept that instead...
My application is extracting data from one DB and inserting the results into a different DB using MySqlDataAdapters and DataSets. I created a unique key in the target DB and want to update values in cases where I recalculated them.
I am hoping to use the data adapter Update method to handle this since there is a variable number of rows to INSERT/UPSERT each time. I also want the update to be as fast as possible since this is a repeating process.
If I exclude the possibility of update and just do inserts my code is functional as follows:
... // dsDSErrors is the dataset returned from my initial query
MySqlCommand cmdLocal = new MySqlCommand(queryLocal, myLocal);
MySqlDataAdapter daLocal = new MySqlDataAdapter(cmdLocal);
daLocal.MissingSchemaAction = MissingSchemaAction.AddWithKey;
DataSet dsLocal = new DataSet();
daLocal.Fill(dsLocal);
foreach (DataRow drError in dsDSErrors.Tables[0].Rows)
{
DataRow curRow = dsLocal.Tables[0].NewRow();
foreach (DataColumn hdr in dsDSErrors.Tables[0].Columns)
curRow[hdr.ColumnName] = drError[hdr.ColumnName];
dsLocal.Tables[0].Rows.Add(curRow);
}
MySqlCommandBuilder bldDSErrors = new MySqlCommandBuilder(daLocal);
daLocal.Update(dsLocal);
I understand that I can use daLocal.InsertCommand = new MySqlCommand(insert command) but was wondering if it is necessary to then loop through the results and add them to the VALUES section of the insert statement or if there was a method I'm not aware of that will handle this.
Barring built in functionality, I assume its best to use string builder to build up the insert query with all my values rows?
i want to create a for loop in which i want to write a query which updates the the value of each row in database. the rows are present in the datagridview as well as in the database. the aim is when the changes are made in datagridview so using a button the change are also applied in the database table too. in each row the barcode and its quantity is different. if the changes are made in all the rows in datagridview so it is also to be applied in database using button and also please help with the parameters.
here is the query which should be considered in the for loop:
SqlCommand cmd2 = new SqlCommand("update prod_info set item_quantity=#qty where barcode=#barcode ", con);
consider barcode as column1 and item_quantity as column2.
so far to create a for loop i have tried this but getting error in the for loops:
for (int i = 0; dataGridView2.Rows.Count; i++) //getting error here
{
SqlCommand cmd2 = new SqlCommand("update prod_info set item_quantity=#qty where barcode=#barcode ", con);
cmd2.Parameters.AddWithValue("#barcode", dataGridView2.Rows[i].Cells[1].Value.ToString());
cmd2.Parameters.AddWithValue("#qty", dataGridView2.Rows[i].Cells[1].Value.ToString());
}
you should call cmd2.ExecuteNonQuery(); in your loop ... otherwise no sql commands will be executed
to get a better solution you should move to creation of cmd2 before the loop. also add the parameters there (without assigning values) ... inside the loop just assign the values and call ExecuteNonQuery.
maybe the best solution would be to use databinding and a SqlDataAdapter with assigned UpdateCommand.
just saw that there probably is an error in your code ... you use the value from Cell[1] for both of your parameters ...
example:
first create a DataTable ... var dt = new DataTable();
then add the columns you want in your grid to the DataTable ... dt.Columns.Add("xyz");
then attach the DataTable to your grid: dataGridView2.DataSource = dt;
now you should be able to edit the contents of column "xyz". to write the values to the database you create a SqlDataAdapter ... var adp = new SqlDataAdapter();
then set adp.InsertCommand = new SqlCommand(...) and adp.UpdateCommand = new SqlCommand(...)
now you can call adp.Update(); and all the values from your grid are written to db ... for newly added rows the InsertCommand is invoked and for edited rows the UpdateCommand is invoked.
I working on windows appliaction which uses Microsoft access as database with oldedb data provider.
In this project I used to import xml file and write the data to database.
I want do bulk insert instead of inserting one record at one time.
So I tried with DAO approch but sometimes ended up with the exception like
"Currently locked unable to update"
Here is the code I used.
using TEST = Microsoft.Office.Interop.Access.Dao;
Pubic void Insert()
{
string sBaseDirectory = (AppDomain.CurrentDomain.BaseDirectory).ToString();
string sODBPath = sBaseDirectory + #"\TEST.accdb";
TEST.DBEngine dbEngine = new TESt.DBEngine();
TEST.Database db = dbEngine.OpenDatabase(sODBPath);
TEST.Recordset rsTest = db.OpenRecordset("dtTest");
for(int i=0;i<1000;i++)
{
rsTest.AddNew();
rsTest.Fields["ID"].Value =i;
rsTest.Fields["Name"].Value ="Test";
rsTest.update();
}
rsTest.close();
db.close();
}
With Oldedb:
DataTable dt = new DataTable();
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("Name", typeof(string));
string TableSQl = "Select * from dtTest where ID=0";
OleDbDataAdapter dataAdapter=new OleDbDataAdapter(TableSQl,ConnectionString);
dataAdapter.InsertCommand = new OleDbCommand(INSERT);
OleDbConnection OleConn = new OleDbConnection(ConnectionString);
for(int i=0;i<1000;i++)
{
dataAdapter.InsertCommand.Parameters.Add("ID", OleDbType.BigInt, 8,i.ToString());
dataAdapter.InsertCommand.Parameters.Add("Name", OleDbType.BigInt, 8, "test");
}
dataAdapter.InsertCommand.Connection = OleConn;
dataAdapter.InsertCommand.Connection.Open();
dataAdapter.update(dt);
dataAdapter.InsertCommand.Connection.Close();
here its not inserting the records in table.
Please guide what is wrong with this code and good approach as well.
See http://msdn.microsoft.com/en-us/library/bbw6zyha(v=vs.80).aspx - 'Using Parameters with a DataAdapter'
The Add method of the Parameters collection takes the name of the
parameter, the DataAdapter specific type, the size (if applicable to
the type), and the name of the SourceColumn from the DataTable.
So you need to create the parameters correctly, populate the DataTable, and then call Update.
Is there any documentation to suggest that this approach will batch the inserts rather than doing them one at a time anyway?
I've got an assignment which requires me to update the northwind database,
I've done everything like the tutorials say as follows
I fill The DataTable Using The DataAdapter.Fill(table).
I build the Delete,Insert,Update Commands using CommangBuilder
SqlDataAdapter adapter = new SqlDataAdapter(selectStr, conn);
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
adapter.DeleteCommand = builder.GetDeleteCommand(true);
adapter.UpdateCommand = builder.GetUpdateCommand(true);
adapter.InsertCommand = builder.GetInsertCommand(true);
adapter.Fill(employees_table);
I also set a primary key for the table:
DataColumn[] employees_keys = new DataColumn[2];
employees_keys[0] = employees.Columns["EmployeeID"];
employees_table.PrimaryKey = employees_keys;
Now I've attempted to delete and add a row:
// accepts an employee object and creates a new new row with the appropriate values for
// an employee table row
DataRow row = ConvertEmployeeToRow(employeeToAdd);
employee_table.Rows.Add(row);`
and deleting a row:
DataRow row = employees.Rows.Find(employeeToDismiss.ID);
employees.Rows.Remove(row);
I should also point out that I've attempted to use row.SetAdded() and row.Delete()
Anyway, at the end when I try to update the database
int k = employees_adapter.Update(employees_table);
on added rows sometimes k get valued, on remove never, and in either case nothing really gets updated at all in the database itself.
Any insight of what I'm doing wrong?
Make sure you're calling employee_table.AcceptChanges() after the call to Update() to save the changes to the database.
Check if the CommandBuilder really makes an Update command for you, like this:
MessageBox.Show(adapter.UpdateCommand.CommandText);
If the primary key info is missing it won't build the update command at all!
I am little confuse here your SqlDataAdapter name is adapter and you are doing updation in employees_adapter.The steps are so simple to work with SqlDataAdapter just follow theses
Step No 1:
SqlDataAdapter adapter = new SqlDataAdapter(selectStr, conn);
SqlCommandBuilder builder = new SqlCommandBuilder(adapter);
DataTable employees_table= new DataTable ();
adapter.Fill(employees_table);
Step No 2:
After you got the data in dataset start manipulation on it..
To insert :
DataRow MyRow = employees_table.NewRow();
//Now Fill data in MyRow
employees_table.Tables[0].Rows.Add(MyRow);
employees_table.AcceptChanges();
adapter.Update(employees_table);
To Delete :
/get only the rows you want
DataRow[] result = employees_table.Select("ID ="+id); //id will be provided by you
//Now do here data updation
employees_table.AcceptChanges()
adapter.Update(employees_table);
Like wise you can apply updation..But after doing any changes must call
table.AcceptChanges() and then'adapter.Update(employees_table)'