I'm trying to somehow update or retrieve again data from Access database (Random piece of data with column names)
I'm using Microsoft.ACE.OLEDB.12.0.
I created a query which should return records where a Column has a value between two dates:
SQL example:
SELECT Arkusz1.ID, Arkusz1.Adres, Arkusz1.Umówione, Arkusz1.Data_umówienia, Arkusz1.Zakończone, Arkusz1.[Spisano?], Arkusz1.Notatki
FROM Arkusz1
WHERE(
((Arkusz1.Umówione) = Yes) // or 1 or <> 0
AND ((Arkusz1.Zakończone) = No) // or 0 doesen't provide right answer
AND ((Arkusz1.Data_umówienia) BETWEEN 24/07/2021 AND 26/07/2021) )
ORDER BY Arkusz1.Data_umówienia;
My code:
void fillGrid()
{
string teraz = DateTime.Today.AddDays(-1).ToShortDateString().Replace('.', '/');
string jutro = DateTime.Today.AddDays(1).ToShortDateString().Replace('.', '/');
// AddDays +-1 because of my data issue, that's not important
string dzisiejsze = "SELECT Arkusz1.ID, Arkusz1.Adres, Arkusz1.Umówione, Arkusz1.Data_umówienia,"
+ " Arkusz1.Zakończone, Arkusz1.[Spisano?], Arkusz1.Notatki FROM Arkusz1"
+ " WHERE( ((Arkusz1.Umówione) = Yes) AND ((Arkusz1.Zakończone) = No) AND "
+ "((Arkusz1.Data_umówienia) BETWEEN "
+ teraz + " AND " + jutro + ") )"
+ " ORDER BY Arkusz1.Data_umówienia;";
//selecting almost every column from my only sheet (Arkusz1),
//if Umówione (appointment is arranged) has True value AND issue is not ended (Zakończone)
//AND appointment date is between yesterday and tomorrow
//(as I said, that's all because my stupid ideas in creating DB)
connection.Open();
OleDbDataAdapter dataAdapter = new OleDbDataAdapter(dzisiejsze, connection);
DataTable dt = new DataTable();
dataAdapter.Fill(dt);
TodaysPlan_dataGridView.DataSource = dt;
TodaysPlan_dataGridView.Refresh();
connection.Close();
}
I even added a special button to update the whole grid (firstly it was supposed to update after a second Form is closed):
private void refreshGrid_Click(object sender, EventArgs e)
{
Application.DoEvents(); // because I saw something on stack, didn't work
fillGrid(); //start filling again, didn't work too
TodaysPlan_dataGridView.Refresh(); // same, didn't work
}
I don't get any error, execution (even in debug-mode) just passes by the code in refreshGrid_Click.
Edit: Tried to execute that SQL code for random data, didn't work too
Ofc that's not the most important part of my question but I could ask that in addition :)
I'll also provide code for saving button from second form, but in my opinion it won't be really helpful:
private void save_button_Click(object sender, EventArgs e)
{
if ((Tick_label.Visible == true) && (IDInfo_label.Text == "All good!") && (street_textBox.TextLength > 0))
{
connection.Open();
string cmd_string = "INSERT INTO Arkusz1 (ID, Adres, Przydzielenie) VALUES ('" + ID_maskedTextBox.Text + "', '" + street_textBox.Text + "','" + startDate_dateTimePicker.Value + "')";
OleDbCommand command = new OleDbCommand(cmd_string, connection);
command.ExecuteNonQuery();
connection.Close();
this.DialogResult = DialogResult.OK;
this.Close();
}
else
{
MessageBox.Show("error");
}
}
That's my first question on Stack, any suggestions and constructive criticism are welcome!
BTW, I was using this YT tutorial, hope it helps someone :)
All right, informations provided by #Steve and #Jimi were really helpful, firstly I changed string formatting using String.Format() and resolved SQL problem - which was (#date#) formatting:
DateTime tmp_teraz = DateTime.Today.AddDays(-1);
string teraz = String.Format("{0}/{1}/{2}", tmp_teraz.Month.ToString(),
tmp_teraz.Day.ToString(), tmp_teraz.Year.ToString());
DateTime tmp_jutro = DateTime.Today.AddDays(1);
string jutro = String.Format("{0}/{1}/{2}", tmp_jutro.Month.ToString(), tmp_jutro.Day.ToString(), tmp_jutro.Year.ToString());
string dzisiejsze = String.Format("SELECT Arkusz1.ID, Arkusz1.Adres, Arkusz1.Umówione, Arkusz1.Data_umówienia, Arkusz1.Zakończone, Arkusz1.[Spisano?], Arkusz1.Notatki FROM Arkusz1 WHERE( ((Arkusz1.Umówione) = true) AND ((Arkusz1.Zakończone) = false) AND ((Arkusz1.Data_umówienia) " +
"BETWEEN (#{0}#) AND (#{1}#)) ) ORDER BY Arkusz1.Data_umówienia;", teraz, jutro);
At the end, grid looks like this.
Refreshing or inserting data with dataGrid doesen't work, but that's a thing I'll develop over time.
Thanks for help and have a nice day guys!
Related
I have a particular part of an inventory interface that requires an employee to select his or her name from a combo box and then scan a product to the table assigned to the name of the employee.
My curiosity is: When hitting the EDIT, ADD OR DELETE button it knows what table to perform this function in from a Switch - Case statement with that employee name on it. The problem is, the piece of code is long for each employee, especially for 9 employees that each have a Switch - Case statement.
Any advice on how to simplify this or shorten the code? I do understand in advance about the parameterized SQL that I am failing to use. Just trying to accomplish this first.
private void btnAdd_Click(object sender, EventArgs e)
{
ActiveControl = txtSerialN;
if (!string.IsNullOrEmpty(txtSerialN.Text) && !string.IsNullOrEmpty(cboEmpName.Text))
switch (cboEmpName.SelectedItem.ToString().Trim())
{
case "John Doe":
try
{
connection.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
command.CommandText = "INSERT INTO JohnDoe(SerialNumber,PartNumber,DateEntered,Customer) values ('" + txtSerialN.Text + "','" + txtPart.Text + "','" + txtDate.Text + "','" + txtCustomer.Text + "')";
command.ExecuteNonQuery();
MessageBox.Show("Inventory Added".PadLeft(23));
connection.Close();
txtSerialN.Clear();
txtPart.Clear();
txtDate.Clear();
txtCustomer.Clear();
command.CommandText = "SELECT * FROM JohnDoe ORDER BY PartNumber";
OleDbDataAdapter db = new OleDbDataAdapter(command);
DataTable dt = new DataTable();
db.Fill(dt);
dataGridEmpParts.DataSource = dt;
}
catch (OleDbException)
{
string strmsg = "THIS SERIAL NUMBER ALREADY EXISTS ! , Please try again";
MessageBox.Show(strmsg, "YOU CAN'T ENTER THE SAME ONE AGAIN", MessageBoxButtons.OK,
MessageBoxIcon.Exclamation,
MessageBoxDefaultButton.Button1);
connection.Close();
}
break;
}
}
I would rather put up a lookup table that will have columns such as EmployeeName, AssignedTable and dynamically construct the commandtext based on the parameter values.
I suspect this problem could more efficiently be fixed by altering the database. Perhaps even as simple as adding a field for employee name.
I am working on a project where the user is displayed a image with hotspots. Upon clicking one part he is displayed a dynamically generated checkbox for which the values are picked from database (hotspot are mapped to value displayed).
The problem I am facing is that when the value is a single word (ex. swelling) the code works fine and fetches the possible diseases, but when there are words like (ex. joint pain or nausea with vomiting) i.e the ones which contain space between them (more than one word as a checkbox value) the code does not work.
Here is the code
protected void Button2_Click(object sender, EventArgs e)
{
if (TextBox2.Text != "")
{
connection.Open();
symptons = String.Join(", ", CheckBoxList1.Items.Cast<ListItem>().Where(i => i.Selected).Select(i => i.Text).ToArray());
Label1.Text = symptons;
string query = symptons.Replace(", ", "','");
string cm = "select distinct dname from disease d inner join diseasesymptom ds on ds.did=d.did inner join symptom s on s.sid=ds.sid where s.sname in ('" + query + "')" + "and days >" + TextBox2.Text + " and days<41 order by (days) desc;";
if (symptons != "")
{
MySqlCommand cmd = new MySqlCommand(cm, connection);
using (MySqlDataAdapter sda = new MySqlDataAdapter())
{
cmd.Connection = connection;
sda.SelectCommand = cmd;
sda.Fill(dt);
GridView1.DataSource = dt;
GridView1.DataBind();
}
}
else
{
Label1.Text = "select at least one symptom";
}
}
else
{
string script = "alert(\"We can't predict without all inputs :(\");";
ScriptManager.RegisterStartupScript(this, GetType(), "ServerControlScript", script, true);
}
}
I think it has something to do with Join and Replace that I am performing.
never mind guys..I got it. I was missing a column value in database that helped in searching (hint : its 'days') . Anyway thanks for anyone who read this. :)
I am trying to create a simple button, that when clicked, adds 1 to the related column. I use a dropdown box to select the ID, then add 1 to the value. However, I am presented with the error:
A first chance exception of type 'System.Data.SqlServerCe.SqlCeException' occurred in System.Data.SqlServerCe.dll
and it highlights cm.ExecuteNonQuery();
I have gone through several attempts at this but it's getting me a little confused as to why I can't simply run the SQL statement.
Here is the code
private void button2_Click(object sender, EventArgs e) {
try {
SqlCeCommand cm = new SqlCeCommand("UPDATE fixedBugs SET Success = Success + 1 WHERE Fixed_ID = '" + comboBox1.Text, mySqlConnection);
cm.ExecuteNonQuery();
} catch (SqlCeException) {
MessageBox.Show("Error");
}
}
"UPDATE fixedBugs SET Success = Success + 1 WHERE Fixed_ID = '" + comboBox1.Text + "'"
Need to close the string parameter with ' in query?
Your command has a opening apostrophe which is not being closed. This should fix it.
SqlCeCommand cm = new SqlCeCommand("UPDATE fixedBugs SET Success = Success + 1 WHERE Fixed_ID = '" + comboBox1.Text + "'", mySqlConnection);
But that's a security issue since the user can manage to add extra commands to your query, which could ruin your entire database.
This is a better solution since using parameters is more safe.
SqlCeCommand cm = new SqlCeCommand("UPDATE fixedBugs SET Success = Success + 1 WHERE Fixed_ID = #fixedid;", mySqlConnection);
cm.Parameters.AddWithValue("#fixedid", comboBox1.Text);
This will prevent future headaches.
This question has better detailed answers that may help enlighten your mind...
You need to think about below things;
User must select a value.
Security
Dispose the command after using it.
string selectedValue = comboBox1.Text;
if (string.IsNullOrEmpty(selectedValue))
{
MessageBox.Show("Please select something");
return;
}
string sql = "UPDATE fixedBugs SET Success = ISNULL(Success,0) + 1 WHERE Fixed_ID = #selectedValue";
try
{
using (SqlCeCommand cm = new SqlCeCommand(sql, mySqlConnection))
{
SqlCeParameter param = new SqlCeParameter("#selectedvalue", SqlDbType.NText);
cm.Parameters.Add(param);
cm.Parameters["#selectedvalue"].Size = 50;
cm.Parameters["#selectedvalue"].Value = selectedValue.Trim();
cm.ExecuteNonQuery();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
PS: Code is not tested.
I'm trying to update my database records, but no changes are made and no error messages. I checked the syntax, the values I'm sending, everything is just fine ..
any suggestions?
This is my code which executed when [save] button is clicked:
ds.UpdateCommand = "UPDATE Users
SET Fullname='" + fname.Text + "',
Permission='" + per.SelectedValue + "',
Email='" + email.Text + "',
phone='" + phone.Text + "'
WHERE UserID=" + Session["userID"].ToString();
ds.Update();
I'm reading values from form filled by the user
ds is an SqlDataSource
If I have to add more details let me know
EDITS:
This page is for user to update his/her information
I'm setting the form values on Page_Load depending on the users information already exist in database.
the user edits his/her info and click [Save]
after setting braekpoints, I found that query string is taking the default values not the new ones. what should I do?
The entire code:
protected void Page_Load(object sender, EventArgs e)
{
Session["userID"] = Request.QueryString["id"];
SqlConnection cn = new SqlConnection();
cn.ConnectionString = ds.ConnectionString;
cn.Open();
SqlCommand cm = new SqlCommand();
cm.Connection = cn;
cm.CommandText = "select * from Users where UserID='" + Session["userID"].ToString() + "'";
SqlDataReader dr;
dr = cm.ExecuteReader();
if (dr.Read())
{
uname.Text = dr["username"].ToString();
fname.Text = dr["Fullname"].ToString();
per.SelectedValue = dr["Permission"].ToString();
email.Text = dr["Email"].ToString();
phone.Text = dr["phone"].ToString();
}
else Response.Redirect("Default.aspx");
dr.Close();
cn.Close();
}
protected void Button3_Click(object sender, EventArgs e)
{
ds.UpdateCommand = "update Users set Fullname='" + fname.Text + "', Permission='" + per.SelectedValue + "', Email='" + email.Text + "', phone='" + phone.Text + "' where UserID=" + Session["userID"].ToString();
ds.Update();
Response.Redirect("control_pan.aspx");
}
Basically, if you have a DataSet and you want to use that to update your database, you need to:
define the UpdateCommand as shown in the MSDN documentation to reference the columns from the DataTable which will be used to update
update an existing row in one of your DataTables inside the DataSet
once you've done that, then you can call .Update() on the data set (or data table) to execute the update - ADO.NET will check for updates to any of the rows of the DataTable, and if an update is found, then the UpdateCommand will be executed, with the parameters bound to the values of the DataTable's row in question
I would also recommend to read up on how the ADO.NET data model and using DataSets and DataTables works in detail - e.g. here Update Data Using .NET DataSets
The alternative, of course, would be to create a SqlConnection and a SqlCommand, using a parametrized query to do the insert yourself, without all the hassle and effort involved with DataSets and DataTables. But in that case, make sure to ALWAYS use parameterized queries (and NEVER just concatenate together your SQL statement including values straight from user input .....) - see why here
I suspect the Session["UserID"] is null. To check this set break point on ds.Update(); by putting the cursor on it then pressing F9.
To see the result query hover your mouse pointer over ds.UpdateCommand when break point pauses operation.
Update: put the code in the page load to be executed only once that is when first the page loads
if(!IsPostBack)
{
//put your code here
}
Update
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
Session["userID"] = Request.QueryString["id"];
SqlConnection cn = new SqlConnection();
cn.ConnectionString = ds.ConnectionString;
cn.Open();
SqlCommand cm = new SqlCommand();
cm.Connection = cn;
cm.CommandText = "select * from Users where UserID='" + Session["userID"].ToString() + "'";
SqlDataReader dr;
dr = cm.ExecuteReader();
if (dr.Read())
{
uname.Text = dr["username"].ToString();
fname.Text = dr["Fullname"].ToString();
per.SelectedValue = dr["Permission"].ToString();
email.Text = dr["Email"].ToString();
phone.Text = dr["phone"].ToString();
}
else Response.Redirect("Default.aspx");
dr.Close();
cn.Close();
}
}
I seriously doubt you've provided enough details here to resolve the issue.
That type is UserID? Does the value need to be enclosed in quotes?
Are you setting the right value in your WHERE clause, and does that value existing in the database? You need to look at the resulting query string and then run it manually to determine what might be wrong.
Also, shouldn't you have the # character prefix for your string so that newlines are part of your string? Is this really what your code looks like?
Of course, without knowing more about the code, it's hard to say what else it might be as well.
I have two DataGridView controls.
For the second one, I just copy-pasted the code from the first and changed where the difference was. But I get an error at the second when I want to view the result of my SQL code.
Translated in English the error show something like that there was no value given to at least one required parameter.
private void button1_Click(object sender, EventArgs e)
{
string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=save.mdb";
try
{
database = new OleDbConnection(connectionString);
database.Open();
date = DateTime.Now.ToShortDateString();
string queryString = "SELECT zivila.naziv,(obroki_save.skupaj_kalorij/zivila.kalorij)*100 as Kolicina_v_gramih "
+ "FROM (users LEFT JOIN obroki_save ON obroki_save.ID_uporabnika=users.ID) "
+ "LEFT JOIN zivila ON zivila.ID=obroki_save.ID_zivila"
+ "WHERE users.ID= " + a.ToString();
loadDataGrid(queryString);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
}
public void loadDataGrid(string sqlQueryString)
{
OleDbCommand SQLQuery = new OleDbCommand();
DataTable data = null;
dataGridView1.DataSource = null;
SQLQuery.Connection = null;
OleDbDataAdapter dataAdapter = null;
dataGridView1.Columns.Clear(); // <-- clear columns
SQLQuery.CommandText = sqlQueryString;
SQLQuery.Connection = database;
data = new DataTable();
dataAdapter = new OleDbDataAdapter(SQLQuery);
dataAdapter.Fill(data);
dataGridView1.DataSource = data;
dataGridView1.AllowUserToAddRows = false;
dataGridView1.ReadOnly = true;
dataGridView1.Columns[0].Visible = true;
}
private void button2_Click(object sender, EventArgs e)
{
string connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=save.mdb";
try
{
database = new OleDbConnection(connectionString);
database.Open();
date = DateTime.Now.ToShortDateString();
string queryString = "SELECT skupaj_kalorij "
+ "FROM obroki_save "
+ "WHERE users.ID= " + a.ToString();
loadDataGrid2(queryString);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return;
}
}
public void loadDataGrid2(string sqlQueryString)
{
OleDbCommand SQLQuery = new OleDbCommand();
DataTable data = null;
dataGridView2.DataSource = null;
SQLQuery.Connection = null;
OleDbDataAdapter dataAdapter = null;
dataGridView2.Columns.Clear(); // <-- clear columns
SQLQuery.CommandText = sqlQueryString;
SQLQuery.Connection = database;
data = new DataTable();
dataAdapter = new OleDbDataAdapter(SQLQuery);
dataAdapter.Fill(data);
dataGridView2.DataSource = data;
dataGridView2.AllowUserToAddRows = false;
dataGridView2.ReadOnly = true;
dataGridView2.Columns[0].Visible = true;
}
You'd be far better off reading and doing this tutorial:
http://msdn.microsoft.com/en-us/library/ms171884(v=VS.80).aspx
It will probably take about 20 minutes to complete
And then (as needed) the rest of them (google for Data Walkthroughs)
They will teach you how to do your data access properly and, after becoming familiar with the advanced tools in Visual Studio for connecting to databases, you'll be able to generate an app that will show database contents in a grid, and save them back to the db, faster than it took you to even write your post here..
The code will be high performance, more secure and easier to write than what you have here - the code you have here is low quality, prone to SQL injection attacks, not modular or arranged in a way that is suited to the language youre using and takes a long time to write; all in, it has no good points at all (please don't be offended)
I thoroughly recommend scrapping the entire thing and starting again, doing things in the way advocated by Microsoft's tutorial. It might seem like the wrong thing to do after you've poured so many hours into this broken, bad way of doing things, but trust me.. You'll be glad you did; 20 minutes investment now will save you thousands of hours of coding in the future
One final point, if your database data doesnt seem to be saving changes when you do things the way the tutorial tells you to, click on the database in Solution Explorer and change "Copy to Output Directory" to "Copy if Newer" - c# is updating your database but youre either looking in the wrong DB to check whether it worked, or Visual Studio is replacing your edited database with a new one every time you start your app
I think the problem is in private void button2_Click() with
a.ToString();
What's a?
Try putting quotes around a.Tostring():
string queryString = "SELECT zivila.naziv,(obroki_save.skupaj_kalorij/zivila.kalorij)*100 as Kolicina_v_gramih "
+ "FROM (users LEFT JOIN obroki_save ON obroki_save.ID_uporabnika=users.ID)"
+ " LEFT JOIN zivila ON zivila.ID=obroki_save.ID_zivila "
+ " WHERE users.ID= '" + a.ToString() + "'";
or use string.format():
string queryString = string.format("SELECT zivila.naziv,(obroki_save.skupaj_kalorij/zivila.kalorij)*100 as Kolicina_v_gramih "
+ "FROM (users LEFT JOIN obroki_save ON obroki_save.ID_uporabnika=users.ID)"
+ " LEFT JOIN zivila ON zivila.ID=obroki_save.ID_zivila "
+ " WHERE users.ID= '{0}'", a);