how can i do multiple update using datatable ?
i found this Update 1 row
my code:
public void ExportCSV(string SQLSyntax, string LeFile, bool Is_Ordre, int TypeDonne)
{
try
{
using (var connectionWrapper = new Connexion())
{
var connectedConnection = connectionWrapper.GetConnected();
SqlDataAdapter da = new SqlDataAdapter(SQLSyntax, connectionWrapper.conn);
DataSet ds = new DataSet();
da.Fill(ds, "Emp");
DataTable dt = ds.Tables["Emp"];
CreateCSVFile(dt, LeFile, Is_Ordre, TypeDonne);
//Update all lines, it not save in Database
foreach (DataRow row in dt.Rows)
{
row["IS_IMPORT"] = true;
}
}
}
catch (Exception excThrown)
{
throw new Exception(excThrown.Message);
}
}
the problem is :
foreach (DataRow row in dt.Rows)
{
row["IS_IMPORT"] = true;
}
it not save it into database.
Thanks you in advance,
Stev
You need to first set the UpdateCommand property on the DataAdapter to the UPDATE statement that will be executed to update a row in the database.
Then, after updating values in the DataTable, you need to pass it to DataAdapter.Update().
This will then execute the UpdateCommand for each updated row in the DataTable.
References:
MSDN - SqlDataAdapter.Update
MSDN - SqlDataAdapter.UpdateCommand
You are updating the value in-memory. The DataTable class is not a sql view, but a memory representation. The Sql Data Adapter only copy the data.
You have to write back the changes to the DB. Try this :
public void ExportCSV(string SQLSyntax, string LeFile, bool Is_Ordre, int TypeDonne)
{
try
{
using (var connectionWrapper = new Connexion())
{
var connectedConnection = connectionWrapper.GetConnected();
SqlDataAdapter da = new SqlDataAdapter(SQLSyntax, connectionWrapper.conn);
da.UpdateCommand = connectedConnection.CreateCommand();
da.UpdateCommand.XXXX = YYYY; // construct the SQL Command
DataSet ds = new DataSet();
da.Fill(ds, "Emp");
DataTable dt = ds.Tables["Emp"];
CreateCSVFile(dt, LeFile, Is_Ordre, TypeDonne);
//Update all lines, it not save in Database
foreach (DataRow row in dt.Rows)
{
row["IS_IMPORT"] = true;
}
da.Update(dt);
}
}
catch (Exception excThrown)
{
throw new Exception(excThrown.Message);
}
}
This should works.
You will have to call da.Update()
Related
I have 2 different databases - SQLite and PostgreSQL and i trying to make tiny math on table from this databases.
Both tables contains columns nr_serii and ilosc, SQLite:
And Postgres:
I established a connection to both databases and populate dataset. Maybe i should use different place to store the data?
I need to substraction column ilosc: (sqlite-postgres), but not know how to do that.
For example, for each nr_serii make substraction column ilosc:
nr_serii:222222
ilosc:15-7=8
Finally i want to show output data to datagridview.
When i use messagebox i can see the data in dataset. Here is my part of code:
string cs = #"URI = file:" + Sdatabase;
string csP = conParam;
string sqlP = "select nr_serii, ilosc from stany";
string sql = "select nr_serii, ilosc from przychod";
using var con = new SQLiteConnection(cs);
con.Open();
using var cmd = new SQLiteCommand(sql, con);
SQLiteDataAdapter da = new SQLiteDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
using var conP = new NpgsqlConnection(csP);
conP.Open();
NpgsqlCommand cmdP = new NpgsqlCommand(sqlP, conP);
NpgsqlDataAdapter DA = new NpgsqlDataAdapter(cmdP);
DataSet dsP = new DataSet();
DA.Fill(dsP);
//----------test-----------
foreach (DataRow row in dsP.Tables[0].Rows)
{
var nr_serii = row["nr_serii"];
var ilosc = row["ilosc"];
MessageBox.Show(nr_serii +","+ ilosc);
}
//--------------------------
For example, you can browse data table from first datasource ds and search for a matching row by value of nr_serii column for each row in the datatable in second datasource dsP, and if found, add a new row with the calculation result to the new third result table.
Then you don't forget to solve the problem of what to do with records that are only in the first ds or only in the second dsP datasource, depending on the value of the nr_serii column.
Program code example:
//prepare result third DataTable
DataTable resultDt = new DataTable();
resultDt.Columns.Add("nr_serii");
resultDt.Columns.Add("ilosc");
//add content to result DataTable
foreach (DataRow row in ds.Tables[0].Rows)
{
var nr_serii = row["nr_serii"];
var ilosc = row["ilosc"];
DataRow drP = null;
foreach (DataRow dataRow in dsP.Tables[0].Rows)
{
if (nr_serii.ToString() == (string)dataRow["nr_serii"])
{
drP = dataRow;
break;
}
}
if (drP != null)
{
var dr = resultDt.NewRow();
dr["nr_serii"] = nr_serii;
dr["ilosc"] = (int)ilosc - (int)drP["ilosc"];
resultDt.Rows.Add(dr);
}
}
I have a table and I want to get specific column from my dataset my table only has one row.
Here is my code
private DataSet Ds = new DataSet();
public DataSet GetDataSet(string Query)
{
try
{
using (MySqlConnection conn = new MySql.Data.MySqlClient.MySqlConnection(connString))
{
MySqlDataAdapter Da = new MySqlDataAdapter(Query, conn);
Da.Fill(Ds);
conn.Close();
}
}
catch (Exception) { }
return Ds; //See image
}
public string getDataCellString(string headerName)
{
return "";//I want to get cell from heder name
}
Here is my question: How can I get a cell value from a header name?
If you only have one row you can:
public string getDataCellString(string headerName)
{
return Ds.Tables[0].Rows[0][headerName].ToString();
}
`Ds.Tables[0].Rows[0]["headerName"].ToString();
I read this question: BackgroundWorker to read database and update GUI
And thinks, that this is a good way to solve this problem.
The only thing is, that I create my Columns dynamically.
I read schemaInfo from DataBase to get the ColumnNames and create a DataGridColumn foreach Column in DataBase.
Now i want to do this with a BackgroundWorker, but u can't update the UI with a BackgroundWorker.
For now (without BackgroundWorker) I have 2 Methods to get the DataBase values.
To load the columns:
using (MySqlDataReader reader = cmd.ExecuteReader())
{
using (DataTable schema = reader.GetSchemaTable())
{
foreach (DataRow col in schema.Rows)
{
DataGridTextColumn column = new DataGridTextColumn();
string columnstring = col.Field<String>("ColumnName");
comboFilter.Items.Add(UppercaseFirst(columnstring));
column.Binding = new Binding(col.Field<String>("ColumnName"));
column.Header = UppercaseFirst(col.Field<String>("ColumnName"));
column.IsReadOnly = true;
Style textStyle = new Style(typeof(TextBlock));
textStyle.Setters.Add(new Setter(TextBlock.TextWrappingProperty, TextWrapping.Wrap));
column.ElementStyle = textStyle;
dataGridPrivatecustomers.Columns.Add(column);
}
}
}
To load values
using (MySqlDataAdapter dataAdapter = new MySqlDataAdapter(string.Format("SELECT * FROM {0}", privateCustomerTablename), connection))
{
using (DataTable dt = new DataTable())
{
dataAdapter.Fill(dt);
dataGridPrivatecustomers.ItemsSource = dt.DefaultView;
}
}
So I tried to make both in one and struggled at creating the result List for the DataGrad's ItemSource:
using (MySqlDataReader reader = cmd.ExecuteReader())
{
int i = 0;
while (reader.Read())
{
using (DataTable schema = reader.GetSchemaTable())
{
foreach (DataRow row in schema.Rows)
{
results.Add(new
{
});
i++;
}
}
}
}
The thing is, that I need to know how I can put the ColumnName + Value in the result List.
In the linked question he did
Id = rdr.GetInt32(0),
But i can't do row.Field<String>("ColumnName") = reader[i].ToString()
The code also don't know how much Columns to add so i guess i need another for or foreach loop ? And how I can set the ColumnName ?
I think that some people want to know this too because (for me) it looks really tricky for beginning Developers who wan't Columns and Values from DataBase to show in a DataGrid with a BackgroundWorker.
So i will show you, how I solved my question.
First I created a List to store all ColumnNames.
private List<string> columnList = new List<string>();
After that I edited the worker_DoWork Event as follows:
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
using (MySqlConnection connection = new MySqlConnection(conf.connection_string))
{
if (OpenConnection(connection))
{
using (MySqlCommand cmd = new MySqlCommand())
{
cmd.Connection = connection;
cmd.CommandText = string.Format("SELECT * FROM {0}", privateCustomerTablename);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
using (DataTable schemaTable = reader.GetSchemaTable())
{
columnList.Clear();
foreach (DataRow row in schemaTable.Rows)
{
columnList.Add(row.Field<String>("ColumnName"));
}
}
}
using (MySqlDataAdapter dataAdapter = new MySqlDataAdapter(cmd.CommandText, connection))
{
using (DataTable dt = new DataTable())
{
dataAdapter.Fill(dt);
e.Result = dt;
}
}
}
connection.Close();
}
}
}
First you can see i made a DataReader to read the DataBase schema and store it in a DataTable so I can loop it trough a foreach loop. In this Loop I add each Item from the schemaTable to my List so the List contains all ColumnNames of the selected DataBase Table.
After that I created a DataAdapter and store the content to another DataTable. And i pass this DataTable via e.Result = dt to the worker_RunWorkerCompleted Event. Now I want to access this data in my worker_RunWorkerCompleted Event.
private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
foreach (var item in columnList)
{
DataGridTextColumn column = new DataGridTextColumn();
column.Binding = new Binding(item);
column.Header = UppercaseFirst(item);
column.IsReadOnly = true;
dataGridPrivatecustomers.Columns.Add(column);
}
DataTable dt = e.Result as DataTable;
dataGridPrivatecustomers.ItemsSource = dt.DefaultView;
}
I loop all items in my columnList and create a DataGridTextColumn for each item in this list and add it to my DataGrid.
After that all Columns are added into my DataGrid and I set the ItemsSource of my DataGrid to the DataTable i passed from worker_DoWork to worker_RunWorkerCompleted.
I've got a dropdown whose values are retrieved from a database. I am retrieving ID and name from the database.
public void GetDepartment_temp()
{
try
{
DataTable dt = new DataTable();
listBoxDepartment.ClearSelection();
Get_Department objDAL = new Get_Department();
dt = objDAL.Get_Hospital_Department();
if (dt != null && dt.Rows.Count > 0)
{
foreach (DataRow row in dt.Rows)
{
listBoxDepartment.Items.Add(new ListItem(row["department_name"].ToString(), row["department_id"].ToString()));
}
}
}
catch (Exception) { }
}
I've got to show the number of employees of each department in the text box. Suppose a user selects human department, then the text box should display the number of employees in that department.
For the ListBox, only two values from the database can be retrieved. How can I show the number of employee in this condition?
public DataTable Get_Hospital_Department()
{
try
{
DataTable dt = new DataTable();
dt = DbAccessHelper.ExecuteDataSet("p_get_hospital_department", true).Tables[0];
return dt;
}
catch (Exception) { return null; }
}
CREATE PROCEDURE [dbo].[p_get_hospital_department]
AS
BEGIN
SET NOCOUNT ON;
SELECT department_id
,department_name
FROM [dbo].[tbl_hospital_department];
END
The statement For the ListBox, only two values from the database can be retrieved. is not correct. You can populate the datatable with as many fields as you want. However, you can set only the Value and text attributes of the Listbox item as you have done.
Change the stored procedure code to fetch the employee count also.
Mark your datatable dt as static and public.
Fetch the datable and you can play with the data as you want. You can fetch the employee count in the textbox on listview selected index changed as shown below:
public static DataTable dt = new DataTable();
public void GetDepartment_temp()
{
try
{
string connString = ConfigurationManager.ConnectionStrings["SOConnectionString"].ConnectionString;
SqlConnection connection = new SqlConnection(connString);
SqlCommand command =
new SqlCommand(
"select Department.DepartmentID, Department.[Department Name], count( Department.DepartmentID) as empCount from Department join Employee on Department.DepartmentID = Employee.DepartmentID group by Department.DepartmentID, Department.[Department Name]",
connection);
command.Connection.Open();
SqlDataAdapter da = new SqlDataAdapter(command);
da.Fill(dt);
dt.PrimaryKey = new DataColumn[] {dt.Columns["DepartmentID"]};
ListBox1.ClearSelection();
if (dt != null && dt.Rows.Count > 0)
{
foreach (DataRow row in dt.Rows)
{
ListBox1.Items.Add(new ListItem(row["Department Name"].ToString(),
row["DepartmentID"].ToString()));
}
}
}
catch (Exception ex)
{
}
}
protected void ListBox1_SelectedIndexChanged(object sender, EventArgs e)
{
DataRow dr = dt.Rows.Find(Convert.ToInt32(ListBox1.SelectedItem.Value));
TextBox5.Text = dr["empCount"].ToString();
}
How to get a specific column value from a DataTable in c#
I have a problem with my code C#.
I need read a specific column value from a DataTable.
I've tried using this solution without success, because the output is the name of column selected in the query (File) and not the value of field database.
I would greatly appreciate any help you can give me in working this problem.
Here is my code:
public DataTable GridViewBind()
{
using (OdbcConnection cn =
new OdbcConnection(ConfigurationManager.ConnectionStrings["cn"].ConnectionString))
{
sql1 = " SELECT FILE FROM tbl_A WHERE Id = 1; ";
using (OdbcDataAdapter command =
new OdbcDataAdapter(sql1, cn))
{
try
{
cn.Open();
dset = new DataSet();
dset.Clear();
command.Fill(dset);
DataTable dt = dset.Tables[0];
GridView1.DataSource = dt;
GridView1.DataBind();
Response.Write(dt.Columns[0].ToString());
return dt;
}
catch (Exception ex)
{
throw new ApplicationException("operation failed!", ex);
}
finally
{
if (command != null)
{
command.Dispose();
}
if (cn != null)
{
cn.Close();
cn.Dispose();
}
}
}
}
}
Edit #1
Now I have error:
System.IndexOutOfRangeException: There is no row at position 0.
public DataTable GridViewBind()
{
using (OdbcConnection cn =
new OdbcConnection(ConfigurationManager.ConnectionStrings["cn"].ConnectionString))
{
sql1 = " SELECT FILE FROM tbl_A WHERE Id = 1; ";
using (OdbcDataAdapter command =
new OdbcDataAdapter(sql1, cn))
{
try
{
cn.Open();
dset = new DataSet();
dset.Clear();
command.Fill(dset);
DataTable dt = dset.Tables[0];
GridView1.DataSource = dt;
GridView1.DataBind();
string file = dt.Rows[0].Field<string>(0);
Response.Write(file.ToString());
return dt;
}
catch (Exception ex)
{
throw new ApplicationException("operation failed!", ex);
}
finally
{
if (command != null)
{
command.Dispose();
}
if (cn != null)
{
cn.Close();
cn.Dispose();
}
}
}
}
}
The table normally contains multiple rows. Use a loop and use row.Field<string>(0) to access the value of each row.
foreach(DataRow row in dt.Rows)
{
string file = row.Field<string>("File");
}
You can also access it via index:
foreach(DataRow row in dt.Rows)
{
string file = row.Field<string>(0);
}
If you expect only one row, you can also use the indexer of DataRowCollection:
string file = dt.Rows[0].Field<string>(0);
Since this fails if the table is empty, use dt.Rows.Count to check if there is a row:
if(dt.Rows.Count > 0)
file = dt.Rows[0].Field<string>(0);
This is pretty simple to achieve. From the DataTable, first we can apply the Select function to get only the row that is associated with Id=1.
After that, we can do the CopyToDataTable() function so as to get it in the DataTable format.
Since, we are expecting that there is only row for Id=1, we can directly apply Rows[0] and then give the column name, convert to string and assign to file variable.
string file = dt.Select("Id=1").CopyToDataTable().Rows[0]["FILE"].ToString()
Note that if you are selecting string value, you need to apply single quotes. For eg, if Id is of string type, then you need to apply like below.
Id='1'