With my program I have a datatable that gets populated with records fetched from a database. This is displayed in a datagrid view and when a cell is clicked it loads all the values into textboxes. When a save button is clicked it will then save the textbox values back into the datatable. However how can I send this datatable back to the database and have it update the records?
Here is my code to load the records:
indexRow = e.RowIndex;
DataGridViewRow row = dgv_ReturnSearch.Rows[indexRow];
tb_editFirstName.Text = row.Cells[1].Value.ToString();
tb_editLastName.Text = row.Cells[2].Value.ToString();
tb_editAge.Text = row.Cells[3].Value.ToString();
tb_editPostCode.Text = row.Cells[4].Value.ToString();
tb_editMobNum.Text = row.Cells[5].Value.ToString();
tb_editEmail.Text = row.Cells[6].Value.ToString();
tb_editAllergies.Text = row.Cells[7].Value.ToString();
tb_editDOB.Text = row.Cells[8].Value.ToString();
tb_editGender.Text = row.Cells[9].Value.ToString();
Here is my code to save them
DataGridViewRow newDataRow = dgv_ReturnSearch.Rows[indexRow];
newDataRow.Cells[1].Value = tb_editFirstName.Text;
newDataRow.Cells[2].Value = tb_editLastName.Text;
newDataRow.Cells[3].Value = tb_editAge.Text;
newDataRow.Cells[4].Value = tb_editPostCode.Text;
Logic.SQLQueriesUtility.Adapter.Update(dt);
However this doesn't actually update the database, only the local datatable. When it is loaded again all the changes revert.
Thanks
To load a gridview with data from the database you'll need to use DataTable and DataAdapter then bind the grid. it should look something like this:
private void CustomersBindGrid()
{
using (SqlConnection con = new SqlConnection(mycon))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = "SELECT * FROM Customers";
cmd.Connection = con;
DataTable dt = new DataTable();
using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
{
sda.Fill(dt);
Gridview1.DataSource = dt;
Gridview1.DataBind();
}
}
con.Close();
}
}
Try updating the database directly:
private void SaveEdits_Click()
{
using (SqlConnection con = new SqlConnection(mycon))
{
con.Open();
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = "UPDATE Customers set firstname= #FN , lastname= #LN , age = #AG , postcode= #PC where CustomerID = #CustID";
cmd.Connection = con;
cmd.Parameters.AddWithValue("#CustID", cid);
cmd.Parameters.AddWithValue("#FN", tb_editFirstName.Text);
cmd.Parameters.AddWithValue("#LN", tb_editLastName.Text);
cmd.Parameters.AddWithValue("#AG", tb_editAge.Text);
cmd.Parameters.AddWithValue("#PC", tb_editPostCode.Text);
cmd.ExecuteNonQuery();
}
}
CustomersBindGrid();
MessageBox.show("Information Updated!");
}
}
You need to edit this update command to your columns in the database and get a way to read the customer id so the condition actually work and update the database.
In your posting, you don't write, how your client is developed...
Normally, this would be done with a SQL update command.
Therefore (in the Microsoft universe) the SqlClient (System.Data.SqlClient Namespace) can be used.
As soon as the user press the save button, you overtake the relevant textbox.text values in variables, change datatypes if necessary, generate an SQL update string to update the data on your SQL server.
Example SQL update string:
Update TableName set ColumnName1Text = 'some text', ColumName2Integer = 12, ColumnName.... = ... where ColumnNameKey = KeyToDatatable
Then you submit the SQL command (SQL update string) to the SQL server via SqlClient (SqlCommand).
But therefore you need a unique key for the where clause (in the example KeyToDatatable) so that only the row with the key is updated.
The key normally is queried from the DataTable (with the other fields) to show the data (in your grid) and then taken over to the update command (can be "hided" from the user, that don't has to know the key).
Well I managed to fix it by doing:
DataGridViewRow newDataRow = dgv_ReturnSearch.Rows[indexRow];
dt.Rows[indexRow]["first_name"] = tb_editFirstName.Text;
dt.Rows[indexRow]["last_name"] = tb_editLastName.Text;
dt.Rows[indexRow]["age"] = tb_editAge.Text;
dt.Rows[indexRow]["postcode"] = tb_editPostCode.Text;
dt.Rows[indexRow]["mobile_num"] = tb_editMobNum.Text;
dt.Rows[indexRow]["email"] = tb_editEmail.Text;
dt.Rows[indexRow]["allergies"] = tb_editAllergies.Text;
dt.Rows[indexRow]["DOB"] = tb_editDOB.Text;
dt.Rows[indexRow]["gender"] = tb_editGender.Text;
Logic.SQLQueriesUtility.Adapter.Update(dt);
Instead of what I was doing before, now it works perfectly and any changes are saved back to the database.
Related
I have two tables in SQL server and I have a form purchaseinvoiceform. it uses a DataGridView to save multiple products.
In save mode this works well. But when I update any order it's updating only the first table which is purchaseinvoice, but isn't updating the second table purchaseinvoicedetails.
purchaseinvoicedetails saves multiple products by their ordernumber.
If I have one item in datagridview it saves successfully.
Now when I update this one item, no problem occurs. But when I add one more item in this order and try to update it, it does not save the other items.
Update query:
SaveOrUpdateProductDetailsOnly("UPDATE [dbo].[PurchaseInvoiceDetails] SET [ProductCode] = #ProductCode ,[ProductName] = #ProductName ,[Box] = #Box,[Quantity] = #Quantity ,[Price] = #Price,[DiscountInPercent] = #DiscountInPercent ,[DiscountAmount] = #DiscountAmount,[Amount] = #Amount WHERE PurchaseInvoiceNo = #PurchaseInvoiceNo");
Here is the Code
How about this?
private void btnUpdate_Click(object sender, EventArgs e)
{
using (SqlConnection con = new SqlConnection("Server=your_server_name;Database=your_database_name;Trusted_Connection=True;"))
{
using (SqlCommand cmd = new SqlCommand("SELECT * FROM Courses", con))
{
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
{
SqlCommandBuilder sqlcmd = new SqlCommandBuilder(da);
DataSet ds = new System.Data.DataSet(); // remove this line
da.Update(this.ds, "Courses");
}
}
}
}
}
I want to grab data from database and display in labels based on what the user selects in the list view.
I'm going off an example that does this with two list views, but I don't know how to do it when I'm sending data to a label.
This is the list view example I'm using (my label code is below this)
private void PopulateRecipeIngredients()
{
string query = "SELECT a.Name FROM Ingredient a " +
"INNER JOIN RecipeIngredient b ON a.Id = b.IngredientId " +
"WHERE b.RecipeId = #RecipeId";
// # is a parameter
using (connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand(query, connection))
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
// whatever recipe is selected in lstRecipes box, get the id of that and pass into query above
command.Parameters.AddWithValue("#RecipeId", lstRecipes.SelectedValue);
// DataTable holds the data return from query
DataTable ingredientTable = new DataTable();
// SqlDataAdapter object adapter fills the ingredientTable DataTable object with results from query
adapter.Fill(ingredientTable);
// Display value of Name ex. salad
lstIngredients.DisplayMember = "Name";
// Id column is how we reference
lstIngredients.ValueMember = "Id";
// connect list box on form to data in recipeTable
lstIngredients.DataSource = ingredientTable;
}
}
MY CODE:
private void PopulateCourseDetails()
{
string query = "SELECT * FROM Course_Info WHERE Id = #CourseId";
using (connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand(query, connection))
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
command.Parameters.AddWithValue("#CourseId", lstCourses.SelectedValue);
DataTable courseTable = new DataTable();
adapter.Fill(courseTable);
lblCourseId.Text = "Course_id";
lblCourseSection.Text = "Course_section";
lblCourseName.Text = "Course_name";
lblCourseDay.Text = "Course_day";
lblCourseStartTime.Text = "Course_start_time";
lblCourseEndTime.Text = "Course_end_time";
lblCourseProfessor.Text = "Course_professor";
lblCourseProfessorEmail.Text = "Course_professor_email";
lstCourses.ValueMember = "Id";
}
}
lblCourseId.Text = (string)courseTable.Rows[0]["Course_id"]
should work as long as you have one row in the result table
Assuming that your DataTable has now been properly populated, you now have a table with a number of rows.
First you need to pull out the first row
var row = courseTable.Rows.FirstOrDefault();
Now you've got a row with a number of columns. You can access each column by either index or column name.
lblCourseId.Text = row[0];
If you want the label to maintain it's header, you can do something like
lblCourseId.Text = "Course_id: " + row[0];
I want to update an Oracle Database table after querying the table and applying an encryption function to the retrieved data from some fields. However, my code (below) does not work correctly:
private void button2_Click(object sender, EventArgs e)
{
using (OracleConnection conn = new OracleConnection(oradb))
conn.Open();
OracleCommand select = new OracleCommand("select empno,FNAME,LNAME from employee", conn);
OracleDataReader reader = select.ExecuteReader();
Int64 vempno = 0;
String fnameValue = "";
String lnameValue = "";
String afterConcatfname = "";
String afterConcatlname = "";
if (reader.HasRows)
{
while (reader.Read())
{
vempno = reader.GetInt64(0);
fnameValue = reader.GetString(1);
lnameValue = reader.GetString(2);
REA rea = new REA();
afterConcatfname = rea.Encrypt(fnameValue, rea.GenerateKey());
afterConcatlname = rea.Encrypt(lnameValue, rea.GenerateKey());
}
reader.Close();
}
OracleCommand update = new OracleCommand("update employee set fname =:fname, lname =:lname where empno =:empno", conn);
OracleParameter fname = new OracleParameter("fname", afterConcatfname);
OracleParameter lname = new OracleParameter("lname", afterConcatlname);
OracleParameter empno = new OracleParameter("empno", vempno);
update.Parameters.Add(fname);
update.Parameters.Add(lname);
update.Parameters.Add(empno);
update.ExecuteNonQuery();
}
I don't receive any error but the program encrypts only the last record with all the encrypted values. I want to encrypt every row.
"I dident receive any error ,but the program encrypts only the last record by all the encrypted values "
That's the logic of your code. Basically, what you are doing is this:
loop
read one row
encrypt one row
end loop
update one row
" I want to encrypt row by row "
So you need to move the update logic into the loop, so that it is executed for each row.
A better solution would be to replace row-by-row processing with a set operation, but that's a different question.
I am using multi column in combo box. So,I would like to display a database table like this photo.
I tried the below coding but I get only the table date without the table borders.
private void affich()
{
SqlConnection connection = new SqlConnection(connectionString);
connection.Open();
req = "select id_amort_fiscal+''+amort_fiscal as combined from amortissementFiscal;";
SqlCommand sql = new SqlCommand(req, connection);
dr = new SqlDataAdapter(req, connection);
dr.Fill(ds, "amortissementFiscal");
multiColumnComboBox1.DataSource = ds.Tables["amortissementFiscal"];
multiColumnComboBox1.DisplayMember="combined";
multiColumnComboBox1.ValueMember = "combined";
connection.Close();
return;
}
this is what I get as a result:
any Help please and thanks :D
Is this third party control?
Anyway your query is showing you are only picking 1 column. Try adding more columns in query.
private void affich()
{
SqlConnection connection = new SqlConnection(connectionString);
connection.Open();
// *******************
// See the new_column2, new_column3 in the below query, replace them
// with your own columns
// ********************
req = "select id_amort_fiscal+''+amort_fiscal as combined, new_column2, new_column3 from amortissementFiscal;";
SqlCommand sql = new SqlCommand(req, connection);
dr = new SqlDataAdapter(req, connection);
dr.Fill(ds, "amortissementFiscal");
multiColumnComboBox1.DataSource = ds.Tables["amortissementFiscal"];
multiColumnComboBox1.DisplayMember="combined";
multiColumnComboBox1.ValueMember = "combined";
connection.Close();
return;
}
Make sure you have assigned ColumnToDisplay property to your MultiColumnCombobox.
multiColumnComboBox1.ColumnsToDisplay = new String[] {"Combinded Fiscal", "First Name"};
This will bind your column data into particular column. To display the proper column header, I preferred to specify alias in your sql query and try to add more columns in your query.
req = "select (id_amort_fiscal+''+amort_fiscal) As [Combinded Fiscal], FName As [First Name] from amortissementFiscal;";
I have filled a DataSet with a Table that was created from another database file. The table is NOT in the database file which I want to be able to copy the Table to.
Now I want to save all those records (DataTable) to a newly created SQLite database file...
How can i do that?
Also I really want to avoid loops if this is possible.
The best answer is by me :) so i'll share it.This is loop but writes 100k entries in 2-3secs.
using (DbTransaction dbTrans = kaupykliuduomConn.BeginTransaction())
{
downloadas.Visible = true; //my progressbar
downloadas.Maximum = dataSet1.Tables["duomenys"].Rows.Count;
using (DbCommand cmd = kaupykliuduomConn.CreateCommand())
{
cmd.CommandText = "INSERT INTO duomenys(Barkodas, Preke, kiekis) VALUES(?,?,?)";
DbParameter Field1 = cmd.CreateParameter();
DbParameter Field2 = cmd.CreateParameter();
DbParameter Field3 = cmd.CreateParameter();
cmd.Parameters.Add(Field1);
cmd.Parameters.Add(Field2);
cmd.Parameters.Add(Field3);
while (n != dataSet1.Tables["duomenys"].Rows.Count)
{
Field1.Value = dataSet1.Tables["duomenys"].Rows[n]["Barkodas"].ToString();
Field2.Value = dataSet1.Tables["duomenys"].Rows[n]["Preke"].ToString();
Field3.Value = dataSet1.Tables["duomenys"].Rows[n]["kiekis"].ToString();
downloadas.Value = n;
n++;
cmd.ExecuteNonQuery();
}
}
dbTrans.Commit();
}
In this case dataSet1.Tables["duomenys"] is already filled with all the data i need to transfer to another database. I used loop to fill dataset too.
When you load the DataTable from the source database, set the AcceptChangesDuringFill property of the data adapter to false, so that loaded records are kept in the Added state (assuming that the source database is SQL Server)
var sqlAdapter = new SqlDataAdapter("SELECT * FROM the_table", sqlConnection);
DataTable table = new DataTable();
sqlAdapter.AcceptChangesDuringFill = false;
sqlAdapter.Fill(table);
Create the table in the SQLite database, by executing the CREATE TABLE statement directly with SQLiteCommand.ExecuteNonQuery
Create a new DataAdapter for the SQLite database connection, and use it to Update the db:
var sqliteAdapter = new SQLiteDataAdapter("SELECT * FROM the_table", sqliteConnection);
var cmdBuilder = new SQLiteCommandBuilder(sqliteAdapter);
sqliteAdapter.Update(table);
If the source and target tables have the same column names and compatible types, it should work fine...
The way to import SQL data to SQLite will take long time. When you want to import data in millions, It will take lot of time. So the shortest and easiest way to do that is just fill fetch the data from SQL database in a DataTable and insert all its rows to SQLite database.
public bool ImportDataToSQLiteDatabase(string Proc, string SQLiteDatabase, params object[] obj)
{
DataTable result = null;
SqlConnection conn = null;
SqlCommand cmd = null;
try
{
result = new DataTable();
using (conn = new SqlConnection(ConStr))
{
using (cmd = CreateCommand(Proc, CommandType.StoredProcedure, obj))
{
cmd.Connection = conn;
conn.Open();
result.Load(cmd.ExecuteReader());
}
}
using (SQLiteConnection con = new SQLiteConnection(string.Format("Data Source={0};Version=3;New=False;Compress=True;Max Pool Size=100;", SQLiteDatabase)))
{
con.Open();
using (SQLiteTransaction transaction = con.BeginTransaction())
{
foreach (DataRow row in result.Rows)
{
using (SQLiteCommand sqlitecommand = new SQLiteCommand("insert into table(fh,ch,mt,pn) values ('" + Convert.ToString(row[0]) + "','" + Convert.ToString(row[1]) + "','"
+ Convert.ToString(row[2]) + "','" + Convert.ToString(row[3]) + "')", con))
{
sqlitecommand.ExecuteNonQuery();
}
}
transaction.Commit();
new General().WriteApplicationLog("Data successfully imported.");
return true;
}
}
}
catch (Exception ex)
{
result = null;
return false;
}
finally
{
if (conn.State == ConnectionState.Open)
conn.Close();
}
}
It will take a very few time as compare to upper given answers.