My C# Datagridview does not show updated data.
This is a Winform, c# application using SQLite. When my form is open, it is showing the data the way it looked before I updated a column on two separate rows using DB Browser for SQLite. In the DB Browser when I execute this SQL: SELECT * FROM SPEAKERS, I see a 10 and a 13 in the column I changed (they used to be a 0 and a 2. This column is defined as an INTEGER.
When I open that particular form, it shows the data in that column as a 0 and a 2. Further down the grid I see 12's and 13's, etc. so it's not a formatting issue on the column. On this form I have an hCDataset, an speakersBindingSource and a speakersTableAdapter. When I right-click on the speakersTableAdapter and choose "Preview Data", it shows the hierarchy of the HCDataSet and the Speakers table under that with the selected object: HCDataSet.Speakers.Fill.Getdata() method. When I hit the Preview button, the data looks exactly like on my datagrid.
Believe me, I've rebooted, closed everything, gone back into the DB Browser for SQLite and every time it opens up with the 10 and 13 in those columns, but it never shows up in the grid on my form with those new updated values in that column.
I thought I could take screenshots, but apparently not. I can paste my screenshots into Paint and they look fine, but apparently when I copy from there and hit CTRL-G in this editor, they don't show up in this document. Maybe I don't have high enough permissions or something.
I've read on other posts that people are having issues updating from the grid and not seeing the updates on the database. I'm kind of having the opposite problem where I update the database, but for some reason the grid isn't showing it.
I've added the code where I'm showing you my connect methods and the code to query the database. When I get to the 3rd row, it display the correct '10' from the RANK column!!
public static SQLiteCommand GetSqliteCommand()
{
SQLiteConnection conn = GetSqliteConnection();
return conn.CreateCommand();
}
public static SQLiteConnection GetSqliteConnection()
{
string dbPath = Path.Combine(Environment.CurrentDirectory, "hc.db");
string connectionString = string.Format("Data Source={0};foreign keys=true", dbPath);
SQLiteConnection conn = new SQLiteConnection(connectionString);
conn.Open();
return conn;
}
//Now my code snippet to read the database and this DOES return the updated column!
GetLastUpdateSql = "SELECT * FROM SPEAKERS ORDER BY ID";
cmd.CommandText = GetLastUpdateSql;
cmd.ExecuteNonQuery();
SQLiteDataReader reader;
reader = cmd.ExecuteReader();
int int1, int2, int3, int4, int5;
string fn, ln;
while (reader.Read())
{
fn = reader["FIRST_NAME"].ToString();
ln = reader["LAST_NAME"].ToString();
int1 = Convert.ToInt32(reader["ID"]);
int2 = Convert.ToInt32(reader["TYPE"]);
int3 = Convert.ToInt32(reader["WARD"]);
int4 = Convert.ToInt32(reader["RANK"]);
int5 = Convert.ToInt32(reader["ACTIVE"]);
}
Related
I'm a student on 3th year of IT and I've found so much help from this forum, I am stuck with my project creating program in C# so I need your help. I have 4 tables in my database but we will focus on 2 of them materijal(Material) table and Skart(Scrap) table:
materijal Table(original) which has:
idmaterijal(INT),
naziv_materijala(VARCHAR),
kolicina_materiala(FLOAT),
mjerna_jedinica(VARCHAR),
sifra_materijala(INT)
material Table(eng) :
idmaterial(INT) ,
name_material(VARCHAR) ,
quantity_material(FLOAT) ,
measuring_unit(VARCHAR) ,
code_material(INT)
skart Table (original) which has:
idskart(INT),
materijal_idmaterijal(INT)
scrap Table(eng) :
idscrap(INT),
material_idmaterial(INT).
They are connected with Non-Identifying Relation 1:1. Now I have a Combo Box in my C# Form presented down below. I need to take from table Materials (name_material, quantity_material, mesuring_unit, code_material) and subtract the quantity that I insert in the textBox on my Form. For example I have 108.15 kg of HR in my Material table and I want to put 45 kg to scrap table , how do I do it in C#...
Pictures:
https://prnt.sc/hdvGuXJWNI0Q - My Diagram in MySQL (It is on my language but I translated every cell name for you guys)
https://prnt.sc/lgIRVTCOe670 - Materials Panel
https://prnt.sc/t1IGxpgJ8GHl - Choosing material via combo box in scraps panel
https://prnt.sc/6InfCPpezZga - Example on how I want to subtract
Down here I had an Idea so you would take from the picture skart panel https://prnt.sc/6InfCPpezZga and insert name_material via comboBox1 (it lists all of the materials from material table ... here I chose HR name of the material) and quantity_material via textBox7 in my case 45 with save button aka button 13 I need to update my material table by taking the quantity_material - textBox7 value and place in my dataGridView3 (witch is showing idscrap and material_idmaterial) code_material, name_material, quantity_material(but quantity I insert in textBox7) and measuring_unit , I know that placing it and showing with dataGridView I have to do the Inner Join or left join but I cant quite understand it ...
private void button13_Click(object sender, EventArgs e)
{
konekcija.Open();
//OleDbCommand komanda = new OleDbCommand();
MySqlCommand komanda = new MySqlCommand();
komanda.Connection = konekcija;
komanda.CommandType = CommandType.Text;
komanda.CommandText = "update materijal set naziv_materijala='" + comboBox1 + "' where kolicina_materijala='" + textBox7.Text + "'";
komanda.ExecuteNonQuery();
konekcija.Close();
comboBox1.Text = "";
textBox7.Text = "";
MessageBox.Show("Uspjesno ste unijeli izabrani Škart");
}
The correct approach for code like this would be something like:
private void UpdateNameFromQuantityButton_Click(object sender, EventArgs e)
{
//konekcija.Open(); //do not keep a connection hanging around; keep a connectionString instead
var sql = "update materijal set naziv_materijala=#nm where kolicina_materijala=#km";
using var konekcija = new MySqlConnection(connectionString);
using var komanda = new MySqlCommand(sql, konekcija);
konekcija.Open();
komanda.Parameters.AddWithValue("#nm", materialNameComboBox.Text);
komanda.Parameters.AddWithValue("#km", quantityTextBox.Text);
var rowsAffected = komanda.ExecuteNonQuery(); //handy to capture this to know if nothing was changed (0 rows affected)
konekcija.Close();
materialNameComboBox.Text = "";
quantityTextBox.Text = "";
MessageBox.Show("Uspjesno ste unijeli izabrani Škart");
}
use using on your command and connection; make a new connection object when you need it. Reusing the same one can cause issues with some databases. The number of MySqlConnection objects in your code is unrelated to the number of actual TCP connections to the database server because TCP connections are pooled by a mechanism elsewhere. Your use of Open and Close actually just leases and returns a pooled connection
always use #parameters in your SQLs to put data into the command. Always*
close your connection as soon as possible after you're done with it
* Unless the "data" is something like a table name or column name in which case it cannot be parameterized; try and avoid such scenarios - it's usually possible
working with an assignment here i am able to view all data from database to grid view but the data appears to be unsorted and it displays all data i only want to display the result of a query in the DataGridView the code i have tried is :
private void btnmeritbsit_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(dbpath);
string query = "select Applicant_no,A_Name,Father_Name,T_Matric,O_Matric,M_Percentage,T_Inter ,O_Inter ,I_Percentage from applicantinfo order by I_Percentage desc";
con.Open();
dataGridView1.ColumnCount = sdr.FieldCount;
SqlCommand cmd = new SqlCommand(query, con);
SqlDataReader sdr = cmd.ExecuteReader();
while (sdr.Read())
{
dataGridView1.Rows.Add(sdr["Applicant_no"], sdr["A_Name"], sdr["Father_Name"], sdr["T_Matric"], sdr["O_Matric"], sdr["M_Percentage"], sdr["T_Inter"], sdr["O_Inter"], sdr["I_Percentage"]);
}
con.Close();
}
i was getting the whole values through datatable and dataAdapter but nothing works !!stuck!!
// DataTable dtbl = new DataTable();
// sda.Fill(dtbl);
// dataGridView1.DataSource = dtbl;
What I wrote in the other answer, in pictures. This is using a VB app, but it doesn't matter because the steps are the same and you're not actually going to be writing much more than one line of code
Right click project, add new dataset
Right click surface, add tableadapter
Add a connection string, Next. Name it, Next
Add a query that selects all from your table, WHERE (id column) = #id
Rename the methods to add "ByID". It will be obvious why later. Finish:
Right click table adapter, Add Query
Proceed through choosing "Select that returns rows" and entering a query that seeks users by last name:
Give good names to the new methods. Finish. Save:
Go to the forms designer, make sure Data Sources tool panel is showing (View Menu)
Drag the Users grid node from Data Sources onto the form
It has pre-made a textbox for the ID, because that's the first query in the tableadapter. We'll change it to lastname. Click the button, change its name, change the text it shows. Always make sure your control names are up to date and relevant.
You can see I changed the label too, and I also changed the name of the textbox (you can't see it) and I changed the name of everything in the tray under the designer, so it starts with underscore:
I do this because VB is case insensitive and calling variable the same name as their type is a bad idea in any language, and makes intellisense confusing in VB. You don't have to add the leading underscores in C#. It's enough to discriminate on case alone, though arguably not always wise:
Now we need to change the code. Double click the FillBy button. It goes to code. Maybe you have some code already, maybe not. Make sure the code fills the table using the relevant input. This is the only part of the process that really requires you to think about what you're doing and what your variables are called (they may be different to mine)
The code probably defaulted to saying
_usersTableAdapter.FillByID(_myDataSet.Users, new Guid(_lastNameToolStripTextBox.Text));
Because it used to be set up for you to type an id (guid or int, my db has a guid) in that box but we have changed it for lastname. So we need to change the FillByID (and now you see why we give them sensible names, not FillBy1 and FillBy2) so it's FillByLastName, and we need to change the code so we pass a string lastname, not a guid ID
_usersTableAdapter.FillByLastName(_myDataSet.Users, _lastNameToolStripTextBox.Text);
That's the only code you have to write. Remember I named my things on the form using leading underscores, so my code has leading underscores. If you dont rename your things, your code won't have leading underscores
Now run the app:
Look at all those John Smiths! They are different users, of course - the ID is different for every one. You can even write new details in here and press save to update the db..
From one line of code! :)
this works perfectly fine just after a few changes :)
private void btnmeritbscs_Click(object sender, EventArgs e)
{
string dbpath = #"Data Source=DESKTOP-UMA0VFO;Initial Catalog=ApplicationForm;Integrated Security=True";
SqlConnection con = new SqlConnection(dbpath);
string query = "select prgstatus,Applicant_no,A_Name,Father_Name,T_Matric,O_Matric,M_Percentage,T_Inter ,O_Inter ,I_Percentage from applicantinfo where prgstatus like 'bscs' order by I_Percentage desc";
SqlCommand cmd = new SqlCommand(query, con);
con.Open();
SqlDataReader sdr = cmd.ExecuteReader();
dataGridView1.ColumnCount = sdr.FieldCount;
while (sdr.Read())
{
dataGridView1.Rows.Add(sdr["prgstatus"], sdr["Applicant_no"], sdr["A_Name"], sdr["Father_Name"], sdr["T_Matric"], sdr["O_Matric"], sdr["M_Percentage"], sdr["T_Inter"], sdr["O_Inter"], sdr["I_Percentage"]);
}
con.Close();
}
The application I am developing is meant to be a quick and easy tool to import data to our main app. So the user loads in a CSV, meddles with the data a little and pushes it up to the database.
Before the data is pushed to the database, I have a verification check going on which basically says, "Does a customer exist in the database with the same name, account and sort codes? If so, put their guid (which is known already) into a list."
The problem is, the result variable is always 0; this is despite the fact that there is duplicate test data already in my database which should show a result. Added to that, using SQL Profiler, I can't see a query actually being executed against the database.
I'm sure that the ExecuteScalar() is what I should be doing, so my attention comes to the Parameters I'm adding to the SqlCommand... but I'll be blowed if I can figure it... any thoughts?
string connectionString = Generic.GetConnectionString("myDatabase");
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand check = new SqlCommand("select COUNT(*) from Customers C1 INNER JOIN CustomerBank B1 ON C1.Id = B1.CustomerId WHERE C1.Name = #Name AND B1.SortCode = #SortCode AND B1.AccountNumber = #AccountNumber", conn);
foreach (DataRow row in importedData.Rows)
{
check.Parameters.Clear();
check.Parameters.Add("#Name", SqlDbType.NVarChar).Value = row["Name"].ToString();
check.Parameters.Add("#SortCode", SqlDbType.NVarChar).Value = row["SortCode"].ToString();
check.Parameters.Add("#AccountNumber", SqlDbType.NVarChar).Value = row["AccountNumber"].ToString();
Object result = check.ExecuteScalar();
int count = (Int32)result;
if (count > 0)
{
DuplicateData.Add((Guid)row["BureauCustomerId"]);
}
}
}
Clarification: importedData is a DataTable of the user's data held in this C# application. During the ForEach loop, each row has various columns, a few of those being Name, SortCode and AccountNumber. The values seem to get set in the parameters (but will verify now).
I guess I need some clarification on how the (My)SqlDataAdapter works. I have a DGV that I use to display one column from a MySQL table; however when I need to edit the record, I need most of the other fields and I do this in another winform. So I guess I need some best practices advice:
Question 1: When binding to the datasource: Do I need to select ALL the fields I want to edit in the form?
string query = "SELECT * FROM cusdata";
cusAdapter = new MySqlDataAdapter(query,pppDB.sqlConn);
cusAdapter.Fill(mainSet,"cusdata");
dgv_cusData.DataSource = mainSet.Tables["cusdata"]
Question 2: I see a lot of info all over the web about selecting just the fields you want to display in the DGV but if I edit that data how does the adapter know exactly what record is being updated on the back-end??
I guess I am just a bit confused about the different approaches and I need some guidance. I want a datagridview where I can display a single column (Customer Name). I want to be able to edit the customer record in another form and have the DVG refreshed with the new information upon successful completion of the Database action.
I have given the best part of a weekend through today to find an article or blog or something that demonstrates EXACTLY that. List-Form paradigm. Can someone please point me in the right direction? Thanks much to the community.
by experience you should not select all the fields, rather select only the fields you need
Select CustId, CustName, CustAddress, CustPhone from cusdata
this will impact performance.
when you edit a data you can use the code below:
string connectionString = "[Put your connection string here]";
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand("UPDATE cusdata SET CustName=#CustName, CustAddress=#CustAddress WHERE CustId=#CustId", conn))
{
cmd.Parameters.AddWithValue("#CustId", 1);
cmd.Parameters.AddWithValue("#CustName", "Name Input");
cmd.Parameters.AddWithValue("#CustAddress", "Address input");
int rows = cmd.ExecuteNonQuery();
//rows number of record got updated
}
}
this part of the code let you specify the fields and data you want to update in your table
cmd.Parameters.AddWithValue("#CustId", 1);
cmd.Parameters.AddWithValue("#CustName", "Name Input");
cmd.Parameters.AddWithValue("#CustAddress", "Address input");
This is for a website in C#,Visual Studio 2010.
I've created a form with many textboxes, a date picker, dropdownlist, etc.
I've created a table in sqlplus with the columns with necessary types(varchar, number, date).
When I click the submit button in my form, I want to store the data in the table I've created.
Just to make it simpler for you guys, assume I have 3 text boxes
(name(text), id, date(i've printed the date in the text box as string)).
When I click submit it should fill the table with these data.
Im struggling to get the OracleCommand to execute this.
cmd = new OracleCommand(______, con);
If there is any other way I can do this by manipulating the types also its welcome :)
The insert syntax for oracle commands generally follows the pattern;
string query = #"INSERT INTO SOME_TABLE VALUES (SOME_COLUMN_1 = :SomeParam1,SOME_COLUMN_2 = :SomeParam2 )";
OracleCommand command = new OracleCommand(query, connection) { CommandType = CommandType.Text };
command.Parameters.Add(":SomeParam1", OracleDbType.Varchar2).Value = "Your Val 1";
command.Parameters.Add(":SomeParam2", OracleDbType.Varchar2).Value = "Your Val 2";
connection.ExecuteNonQuery();
See more reference examples here;
Using Named Parameters with Oracle ODP.NET