Having problem reading a value from my table in mysql, is the index value i cant read the value back no matter what. all i get is the initialized value of 0 i dont get any error because it return 0, if i run the query in the database it get the correct value. i tried to use executeScalar() but with the same result .
MySqlConnection conn = new MySqlConnection(MyConString);
ulong ukey=0;
try
{
string sql_users2 = "SELECT `key` FROM `permuser` WHERE `user` = '" + myuser + "' AND `code` = '" + mycode + "'";
MySqlCommand cmdSel2 = new MySqlCommand(sql_users2, conn);
conn.Open();
MySqlDataReader dr2 = cmdSel2.ExecuteReader();
dr2.Read();
ukey = dr2.GetUInt64(dr2.GetOrdinal("key"));
// MessageBox.Show("Sorry " + myuser + " already have access to " + mycode + ",\nIf this is an extension, search for the user which key is " + ukey + " and edit the end date.", "Duplicate User Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
dr2.Close();
dr2.Dispose();
}
catch (MySqlException ex) //catch 2
{
MessageBox.Show("catch ukey\nCan't connect to database\n" + ex.ToString());
}
conn.Close();
conn.Dispose();
You are returning a single value from your query, so you could use directly ExecuteScalar instead of ExecuteReader. (the link point to the description for SqlServer, but it is the same for MySql)
An important question to never forget is the usage of parameters instead of string concatenation.
What happen if your myuser or mycode variables contain a single quote? You get wrong results or syntax errors.
Of course, the main problem is the Sql Injection attack to never understimate.
using(MySqlConnection conn = new MySqlConnection(MyConString))
{
ulong ukey=0;
try
{
string sql_users2 = "SELECT `key` FROM `permuser` WHERE `user` = #usr AND `code` = #code";
MySqlCommand cmdSel2 = new MySqlCommand(sql_users2, conn);
conn.Open();
cmdSel2.Parameters.AddWithValue("#usr", myuser);
cmdSel2.Parameters.AddWithValue("#code", mycode);
object result = cmdSel2.ExecuteScalar();
if(result != null)
ukey = Convert.ToUInt64(result);
}
catch (MySqlException ex) //catch 2
{
MessageBox.Show("catch ukey\nCan't connect to database\n" + ex.ToString());
}
}
also I am a bit perplexed about your usage of UInt64. What kind of datatype is stored in the key column?
way is many simply:
ukey = (uint)dr2[0];
Related
I have a problem where if i search for data via a TextBox and the data doesn't exist in the database i get the error
'Object cannot be cast from DBNull to other types.'
I am trying to make a MessageBox appear to say data doesn't exist and cannot figure out how to do this.
I have tryed using an if statement where if the TextBox equals DBNull then a MessageBox appears. this doesnt work and im not too sure why. The error occurs with me trying to **equal** toDBNull. How do i produce aTextBox` saying data doesnt exist?
{
SqlConnection con = new SqlConnection("***COnString**");
con.Open();
SqlCommand comm = new SqlCommand("SELECT SUM (Total_Hours_Day) FROM Sign_In_Out_Table, User_Table WHERE User_Table.FirstName = '" + Search_Username_Alerts_Admin_txtbox.Text + "' AND Sign_In_Out_Table.eb_number = User_Table.eb_number AND Date between GETDATE()-14 and GETDATE()", con);
decimal TotalHoursFortnight = Convert.ToDecimal(comm.ExecuteScalar());
con.Close();
decimal sum = 0;
sum += Convert.ToDecimal(TotalHoursFortnight);
if (Search_Username_Alerts_Admin_txtbox.Text == DBNull)
{
MessageBox.Show("No Data Exists");
}
else
{
MessageBox.Show(Search_Username_Alerts_Admin_txtbox.Text + ":" + Environment.NewLine + " Hours Worked = " + TotalHoursFortnight, ("Working Info Admin"), MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
My expected result is for a message box to appear saying data doesn't exist if searched for. but if it does the data will show in a message box.
You have 3 cases to implement:
No data at all: check for null
Invalid data, e.g. 1 + 2 + NULL + 3 == NULL: check for DBNull.Value
Valid data, e.g. 1 + 2 + 3 == 6: convert it with a help of Convert.ToDecimal()
Code:
// wrap IDisposable into using
using (SqlConnection con = new SqlConnection("***COnString**")) {
con.Open();
//DONE: Make sql readable
//DONE: Make sql parametrized
//TODO: you may want to change eb_number = eb_number into INNER JOIN
string sql =
#"SELECT SUM (Total_Hours_Day)
FROM Sign_In_Out_Table,
User_Table
WHERE User_Table.FirstName = #prm_FirstName
AND Sign_In_Out_Table.eb_number = User_Table.eb_number
AND Date BETWEEN GETDATE() - 14 AND GETDATE()";
using (SqlCommand comm = new SqlCommand(sql, con)) {
//TODO: Better specify RDBMS type explictly with "comm.Parameters.Add(...)"
comm.Parameters.AddWithValue(
"#prm_FirstName", Search_Username_Alerts_Admin_txtbox.Text);
var result = comm.ExecuteScalar();
if (null == result) { // No Data
MessageBox.Show("No Data Exist");
}
else if (DBNull.Value == result) { // We have the Data and it's RDBMS Null
MessageBox.Show("Data Exist, but not valid.");
}
else { // We have a valid Decimal
Decimal sum = Convert.ToDecimal(result);
//TODO: put the relevant code here
}
}
}
I would use decimal.tryparse to see if data was returned
SqlConnection con = new SqlConnection("***COnString**");
con.Open();
SqlCommand comm = new SqlCommand("SELECT SUM (Total_Hours_Day) FROM Sign_In_Out_Table, User_Table WHERE User_Table.FirstName = '" + Search_Username_Alerts_Admin_txtbox.Text + "' AND Sign_In_Out_Table.eb_number = User_Table.eb_number AND Date between GETDATE()-14 and GETDATE()", con);
string TotalHoursFortnight = (comm.ExecuteScalar()).ToString();
con.Close();
decimal sum = 0;
decimal temp;
if(!decimal.TryParse(TotalHoursFortnight, out temp))
{
MessageBox.Show("No Data Exists");
}
else
{
sum += temp;
MessageBox.Show(Search_Username_Alerts_Admin_txtbox.Text + ":" + Environment.NewLine + " Hours Worked = " + TotalHoursFortnight, ("Working Info Admin"), MessageBoxButtons.OK, MessageBoxIcon.Information);
}
You need check null for query result
var result = comm.ExecuteScalar();
if(result != null){
decimal TotalHoursFortnight = Convert.ToDecimal(comm.ExecuteScalar());
// move remain code to if block
}
And if (Search_Username_Alerts_Admin_txtbox.Text == DBNull) should change to
if (Convert.IsDBNull(Search_Username_Alerts_Admin_txtbox.Text){
}
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 want to save images in SQL database when selected by users. So far i have typed this code. This doesn't give me any error but doesn't add to the database.
I think something is wrong with the SQL Statement.
can someone help me?
This is my code:
public void addImages(string tag1,string tag2,string tag3,string status,string fileName)
{
try
{
byte[] image = null;
FileStream fsstream = new FileStream(fileName,FileMode.Open,FileAccess.Read);
BinaryReader br = new BinaryReader(fsstream);
image = br.ReadBytes((int)fsstream.Length);
SqlCommand command = new SqlCommand("INSERT INTO [ImagesAndTags] (Images,Tags,Tag2,Tag3,Status) values (#IMG,'" + tag1 + "','" + tag2 + "','" + tag3 + "','" + status + "')", con);
con.Open();
command.Parameters.Add(new SqlParameter("#IMG",image));
SqlDataReader reader = command.ExecuteReader();
MessageBox.Show("Added Successfully!!!", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
while (reader.Read()) { }
}
catch(Exception ex) { }
}
ExecuteReader returns data. In your case, you are not. You just try insert a row in your database. That's why you need to use ExecuteNonQuery instead.
And parameterize your other insert values as you did for image variable. Also use using statement to dispose your database connections and commands.
int insertedRowCount = command.ExecuteNonQuery();
if(insertedRowCount > 0)
MessageBox.Show("Added Successfully!!!", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
Remove all the backslash, single inverted-commas and double inverted commas from the DATA you are storing in the database.
Replace it with some constant string and while retrieving it back again convert it to original.
In my winforms application i want to update database values using form. i managed to create every other part get to work other than this.when i tried to update my database it giving me some strange sql error. i have not idea what's wrong with my code
it shows me error like this
you have an error in your sql syntax check the manual that corresponds to your mysql server version
and this is the code that i used to update the database.can someone please check this code for me
private void button1_Click(object sender, EventArgs e)
{
string constring = string.Format("datasource='{0}';username=***************;port=3306;password=**********;Connect Timeout=20000;Command Timeout=28800", serverip.Text);
string Query = "update wartif.userdata set (citrixpass= '" + this.citrix_pass_box.Text + " ', idmpass = '" + this.IDM_pass_box.Text + "' , mortracpass = '" + this.mortrac_pass_box.Text + "' , detpass = '" + this.DET_pass_box.Text + "' where username = '" + this.Pwloggeninaslable.Text + "' ;";
MySqlConnection conwaqDatabase = new MySqlConnection(constring);
MySqlCommand cmdwaqDatabase = new MySqlCommand(Query, conwaqDatabase);
MySqlDataReader myreader;
try
{
conwaqDatabase.Open();
myreader = cmdwaqDatabase.ExecuteReader();
while (myreader.Read()) { }
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
You open a parenthesis before the SET clause (not needed) but you forget to close it at the end
However, let me show you how you should write this code to avoid sql injection and parsing problems
string constring = .....;
string Query = #"update wartif.userdata set citrixpass=#ctx, idmpass = #idm,
mortracpass = #mtc, detpass = #det where username = #usr;";
using(MySqlConnection conwaqDatabase = new MySqlConnection(constring))
using(MySqlCommand cmdwaqDatabase = new MySqlCommand(Query, conwaqDatabase))
{
try
{
conwaqDatabase.Open();
cmdwaqDatabase.Parameters.AddWithValue("#ctx", this.citrix_pass_box.Text);
cmdwaqDatabase.Parameters.AddWithValue("#idm", this.IDM_pass_box.Text);
cmdwaqDatabase.Parameters.AddWithValue("#mtc", this.mortrac_pass_box.Text);
cmdwaqDatabase.Parameters.AddWithValue("#det", this.DET_pass_box.Text);
cmdwaqDatabase.Parameters.AddWithValue("#usr", this.Pwloggeninaslable.Text);
int rowsUpdated = cmdwaqDatabase.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
In this way you don't need to worry about malicious user that tries to break your code with an Sql Injection attack, your query string is more readable and you don't need to worry about passing strings that contains single quote or correctly formatting dates and decimals
I tried going through my code for hours trying to see where I went wrong and google doesn't seem to have the answer either.
Basically I am running this code:
public bool LoginRequest(string ReceivedUsername, string ReceivedPassword)
{
bool ValidLogin = false;
try
{
using (SqlConnection myConnection = new SqlConnection(ConnectString))
{
myConnection.Open();
Log.Debug("Succesful sql connection");
SqlCommand userSELECTcom = new SqlCommand("SELECT username,password FROM users;", myConnection);
SqlDataReader reader = userSELECTcom.ExecuteReader();
//verify login
while (reader.Read())
{
CompareUsername = reader["username"].ToString();
ComparePassword = reader["password"].ToString();
Log.Debug(ReceivedUsername + " against " + CompareUsername);
Log.Debug(ReceivedPassword + " against " + ComparePassword);
if (CompareUsername == ReceivedUsername && ComparePassword == ReceivedPassword)
{
ValidLogin = true;
Log.Debug(ReceivedUsername + " has logged in successfully!!!");
myConnection.Close();//close sql conn
reader.Close();//close sqldatareader
return ValidLogin;
}
else if (CompareUsername != ReceivedUsername || ComparePassword != ReceivedPassword)
{
if (!reader.Read())
{
Log.Debug(ReceivedUsername + " has not logged in successfully with password: " + ReceivedPassword);
myConnection.Close();//close sql conn
reader.Close();//close sql data reader
return ValidLogin;
}
}
}
//end of verify sequence
}
}
//logging any login request issues
catch (Exception e)
{
Log.Debug(e);
}
return ValidLogin;
}
I have a logging program set up that tells me everything thats happening as the code gets executed. These lines: " Log.Debug(ReceivedUsername + " against " + CompareUsername);
Log.Debug(ReceivedPassword + " against " + ComparePassword); "
helps me see which row is being checked by the reader. I tried with six rows each with unique usernames and passwords and the result basically shows that only row 1, 3 and 5 is checked by the reader against the input from the user. So if I tried to log in with my client using a username and password from row 2, 4 or 6 I get an error saying my log in failed. Can anyone explain why this happens?
You have an extra Reader.Read() call in your condition where you didn't find the login that time. That's skipping to the next record, then your main loop's Reader.Read() goes to the next.
You don't need to loop like this, though. Build a query that looks for a record by the username. If there are no records, login fails. If there is one, check the password.
You have a 2nd reader.Read() on the if statement inside the while block. That is causing your code to skip a record.
To keep things simple you could directly query from database.
Below is example code to check if the received username and password exists in the db:
string sql = #"SELECT username,password FROM users
WHERE username=#username and password = #password";
SqlCommand userSELECTcom = new SqlCommand(sql, myConnection);
userSELECTcom.Parameters.AddWithValue(#username, ReceivedUsername);
userSELECTcom.Parameters.AddWithValue(#password, ReceivedPassword);
using(SqlDataReader reader = userSELECTcom.ExecuteReader())
{
ValidLogin = reader.HasRows;
}
else if (CompareUsername != ReceivedUsername || ComparePassword != ReceivedPassword)
{
if (!reader.Read()) //remove this condition it will skip the current loop
{
Log.Debug(ReceivedUsername + " has not logged in successfully with password: " + ReceivedPassword);
myConnection.Close();//close sql conn
reader.Close();//close sql data reader
return ValidLogin;
}
}