Path Stored in database is not right - c#

private void button14_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
string c = openFileDialog1.FileName;
string connString = "Server=Localhost;Database=test;Uid=root;password=root;";
MySqlConnection conn = new MySqlConnection(connString);
MySqlCommand command = conn.CreateCommand();
command.CommandText = ("Insert into data (path) values('" + c + "')");
conn.Open();
command.ExecuteNonQuery();
conn.Close();
MessageBox.Show("Success");
}
}
This code works for me, but unfortunately, the path stored in database is not right .. the stored path is like this (C:Users hesisDesktopREDEFENSEResourcesImagesRED1f.png) where it supposed to be like this (C:P/Users/thesis/Desktop..../1f.png).
But when I checked the "sr" value with this code.. the msgbox show just right..
private void button14_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
MessageBox.Show(openFileDialog1.FileName);
}
}
why is it happening then?

Perhaps MySQL thinks that the "\" character is an escape, so that's why it does not contain it in the string. Try
c.Replace(#"\", #"\\")
when you insert, so the escape character will be escaped.
EDIT: For example, replace the command text initializing line like this. Also add an escape for single quotes.
string escapedPath = c.Replace(#"\", #"\\").Replace("'", #"\'");
command.CommandText = ("Insert into data (path) values('" + escapedPath + "')");
EDIT: See #Matthew's answer for an even more "best practice" solution, using parameterized queries.

This is due to the way you're writing your query. In MySQL, the backslash character \ (which is present in file paths) has special meaning, which is to escape the next character. You need to encode these, many different DBMS's have patterns to do this.
Other than that, your code is susceptible to SQL injection.
To fix both these problems, you can use parametrized queries.
public void InsertPath(string path)
{
string connString = "Server=Localhost;Database=test;Uid=root;password=root;";
using (var connection = new MySqlConnection(connString))
{
connection.Open();
using (var command = connection.CreateCommand())
{
command.CommandText = "INSERT INTO data(path) VALUES(?path)";
command.Parameters.AddWithValue("?path", path);
command.ExecuteNonQuery();
}
}
}
This answer might not be 100% accurate, because I don't have MySQL on my computer, but hopefully if it doesn't work, it should at least give you some information about how to approach this problem.

Why aren't you using a parameterized query? You can avoid most of the trouble with escaping strings, prevent a whole class of security risks, and gain a tiny bit of performance from query caching if you do.
Normally, it looks something like this:
cmd.CommandText = "INSERT INTO data (path) values(?path)";
cmd.Prepare();
cmd.Parameters.AddWithValue("?path", c);
It's been long enough since I've written any explicity C# query code (6 months or so) that I can't remember if this is exactly right, and I know the MySql provider uses a slightly different parameterization convention than MSSQL for named parameters (which uses #path instead of ?path), but that should get you on the right path. See C# MySqlParameter problem for a little more guidance that might be relevant to you.

Related

How do I delete an entire row from a database

How would I delete a row from a sql database, either with stored procedures or without, right now I have tried without, using a button press.
This is what I have so far, _memberid has been sent over from a differnt form from the database(For context).
private void btnDelete_Click(object sender, EventArgs e)
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = Lib.SqlConnection;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "Delete * From Members where MemberId = " + _memberId;
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.DeleteCommand = cmd;
adapter.Fill(MembersDataTable); // Im fairly sure this is incorrect but i used it from old code
DialogResult = DialogResult.OK;
}
If you're trying to do a simple ADO.Net-based delete, then it would be somehting like his:
private void DeleteById(int memberId)
{
// or pull the connString from config somewhere
const string connectionString = "[your connection string]";
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
using (var command = new SqlCommand("DELETE FROM Members WHERE MemberId = #memberId", connection))
{
command.Parameters.AddWithValue("#memberId", memberId);
command.ExecuteNonQuery();
}
}
Use parameter to prevent SQL injection.
There are essentially three main things I'm seeing...
One
You don't need the * in the query. DELETE affects the whole row, so there's no need to specify columns. So just something like:
DELETE FROM SomeTable WHERE SomeColumn = 123
Two
There's no need for a SqlDataAdapter here, all you need to do is execute the query. For example:
cmd.ExecuteNonQuery();
The "non query" is basically a SQL command which doesn't query data for results. Inserts, updates, and deletes are generally "non queries" in this context. What it would return is simply the number of rows affected, which you can use to double-check that it matches what you expect if necessary.
Three
Don't do this:
cmd.CommandText = "Delete From Members where MemberId = " + _memberId;
This kind of string concatenation leads to SQL injection. While it looks intuitively like you're using _memberId as a query value, technically you're using it as executable code. It's less likely (though not impossible) to be a problem for numeric values, but it's a huge problem for string values because it means the user can send you any string and you'll execute it as code.
Instead, use query parameters. For example, you might do something like this:
cmd.CommandText = "Delete From Members where MemberId = #memberId";
cmd.Parameters.Add("#memberId", SqlDbType.Int);
cmd.Parameters["#memberId"].Value = _memberId;
This tells the database engine itself that the value is a value and not part of the executing query, and the database engine knows how to safely handle values.
You could use a DataAdapter, but since you aren't using a datatable, it's just easier to do it without like this:
var sql = "DELETE FROM Members WHERE MemberId=#MemberId";
using(var cmd = new SqlCommand(sql, Lib.SqlConnection))
{
cmd.Connection.Open();
cmd.Parameters.Add("#MemberId",SqlDbType.Int).Value = _memberId;
cmd.ExecuteNonQuery();
}
And if you are using Dapper, you can do this:
Lib.SqlConnection.Execute("DELETE FROM Members WHERE MemberId=#MemberId", new {MemberId=_memberId});
If you are still using DataTables, I would highly recommend you look into using this (or something like this) to simplify your database accesses. It'll make CRUD logic on a database a breeze, and your code will me a lot more maintainable because you can get rid of all the odd needs to do casting, boxing/unboxing, and reduce the chances of runtime bugs because of the use of magic strings that happens so often with DataTables (column names). Once you start working with POCO classes, you'll hate having to use DataTables. That said, there are a few places where DataTables are a better solution (unknown data structures, etc), but those are usually pretty rare.

Updating Table in asp.net

protected void Button1_Click(object sender, EventArgs e)
{
if(FileUpload1.HasFile)
{
int Id = Convert.ToInt32(Request.QueryString["Id"]);
String fileName = Path.GetFileName(FileUpload1.PostedFile.FileName);
FileUpload1.SaveAs(Server.MapPath("~/Order/" + fileName));
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["RegistrationConnectionString"].ToString());
con.Open();
String Update =("Update Order set DesignedImage=#DesignedImage where Id=#Id");
SqlCommand cmd = new SqlCommand( Update , con);
cmd.Parameters.AddWithValue("#DesignedImage", "Order/" + fileName);
cmd.Parameters.AddWithValue("#Id", + Id);
cmd.ExecuteNonQuery();
con.Close();
Label1.Text = "OK";
}
I want to update table Order.
this code is giving me syntax error near keyword Order
Order is a reserved keyword in T-SQL. You need use it with square brackets as [Order].
As a best practice, change it to non-reserved word.
It would be better to use using statement to dispose your connection and command automatically instead of calling Close or Dispose methods manually.
Also don't use AddWithValue as much as you can. It may generate unexpected and surprising results sometimes. Use Add method overload to specify your parameter type (SqlDbType) and it's size.
As a last thing, Open your connection just before you execute your command.
You cannot have Order as your table name since it is reserved keyword on sql queries.
Rename the table and try.

What is wrong with this query, its show only increment, assignment etc can be used as argument?

Check the bold oledb command, idont know what kind of error it is , or what im doing wrong
please help :(
private void button1_Click(object sender, EventArgs e)
{
try
{
string constring = #"Provider = Microsoft.Jet.OLEDB.4.0; Data Source=C:\Users\ShahMuhammad\Desktop\testLogin.accdb; Persist Security Info=True;";
OleDbConnection conDataBase = new OleDbConnection(constring);
***OleDbCommand cmdDatabase = new OleDbCommand("Select * from login where uname="this.textBox1.Text" and pword = "this.textBox2.Text", connDatabase);***/// HERE I HAVE PROBLEM
OleDbDataReader myReader;
conDataBase.Open();
myReader = cmdDatabase.ExecuteReader();
int count=0;
while(myReader.Read())
{count=count+1}
if(count==1)
{MessageBox.Show("Successfull Login");}
else if (count >1)
{MessageBox.Show("Duplicate Uname or Password");}
else
MessageBox.Show("Ghalat input ustaad, wari account password");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
kindly tell me whats is the error , i am a total newbie in C# programming, specially connecting with db
You have a problem because uname and pword are text fields.
When you query text fields you need to put the values between single quotes.
However there is a better solution and it is called Parameterized query
OleDbCommand cmdDatabase = new OleDbCommand(#"Select * from login
where uname=#name and pword = #pword",
connDatabase);
cmdDatabase.Parameters.AddWithValue("#name", textBox1.Text);
cmdDatabase.Parameters.AddWithValue("#pword",textBox2.Text);
....
No more problems with quoting string, replacing single quotes inside strings and Sql Injection attacks, and your command text is now a lot more readable.
When you have fixed this problem I also suggest to read about the weakness of storing passwords in clear text inside a database. In your case a malicious user can simply copy the database and he/she can easily read all your users passwords.
EDIT
Revisiting this question after an hour and I see that there are multiple correct answers (Soner Gönül and Paul Zahra) to your question (albeit incomplete including mine).
In a summary:
Concatenating strings in C# is done using the + operator
There is a typographical error in your naming the connection
Passing string values to a database should be done enclosing strings
in quotes
Use the using statement around disposable objects
Finally use a parameterized query when dealing with command texts
"Select * from login where uname="this.textBox1.Text" and pword = "this.textBox2.Text"
I think this should be;
"Select * from login where uname=" + this.textBox1.Text + "and pword =" + "this.textBox2.Text
If your columns are not character typed, othwerwise you need to use single quotes with them.
But as a better way, always use parameterized queries. This kind of string concatenations are open for SQL Injection attacks.
var cmdDatabase = new OleDbCommand("Select * from login where uname= ? and pword = ?", connDatabase);
cmdDatabase.Parameters.Add("p1", OleDbType...).Value = this.textBox1.Text;
cmdDatabase.Parameters.Add("p2", OleDbType...).Value = this.textBox2.Text;
And use using statement to dispose your OleDbCommand, OleDbConnection and OleDbDataReader. Like;
using(OleDbConnection conDataBase = new OleDbConnection(constring))
using(OleDbCommand cmdDatabase = conDataBase.CreateCommand())
{
...
...
using(OleDbDataReader myReader = comm.ExecuteReader())
{
//
}
}
Finally, looks like you store your passwords as a plain text. Don't do that! Read: Best way to store password in database
You have two issues with your code... as others have pointed out you need to concatenate the strings... the other is your db connection object, it is called conDataBase but you reference connDataBase and your sql string is a bit squiffy ... your code should look like...
OleDbConnection conDatabase = new OleDbConnection(constring);
string sql = "Select * from login where uname='" + this.textBox1.Text + "' and pword = '" + this.textBox2.Text + "'"
OleDbCommand cmdDatabase = new OleDbCommand(sql, conDatabase);
but as others have said using a parameterised query is safer.
you should write 'this.textbox1.text' (+this.textbox1.text+)
ur query should be like this
"select * from TblLogin where UserName='"+this.txtUserName.text+"' and Password='"+this.txtPassword.text+"' ";

Creating Registration form in c# with mysql

Hello so i m creating a registration form in C# with MySql so it connects to the database and everything but i get this error Napaka pri registraciji Unknown column " in 'field list' the translation of Napaka pri registraciji means Error at registering i just have it in my language. I get this error when i insert data in textboxes and press Register..
the code:
private void btn_Reg_Click(object sender, EventArgs e)
{
MySqlConnection dataConnection = new MySqlConnection();
dataConnection.ConnectionString = "datasource=localhost;port=3306;username=root;password=";
dataConnection.Open();
MySqlTransaction transakcija = dataConnection.BeginTransaction();
MySqlCommand dataCommand = new MySqlCommand();
dataCommand.Connection = dataConnection;
dataCommand.Transaction = transakcija;
try
{
dataCommand.CommandText = "Insert INTO lr.users (upIme,geslo) VALUES (`"+this.tB_upIme.Text+"`,`"+this.tB_geslo.Text+"`)";
dataCommand.CommandType = CommandType.Text;
dataCommand.ExecuteNonQuery();
transakcija.Commit();
MessageBox.Show("Registracija uspešna!");
}
catch (Exception eks)
{
transakcija.Rollback();
MessageBox.Show("Napaka pri registraciji\n" + eks.Message);
}
finally
{
dataCommand.Connection.Close();
}
}
There are two things I immediately see wrong here...
First, you're using back ticks to wrap your values. In MySQL Back ticks represent database objects, so the query is looking for objects named by those values instead of using the values themselves. So instead of this:
`"+this.tB_upIme.Text+"`
You'd want this:
'"+this.tB_upIme.Text+"'
Second, and vastly more importantly, your code is wide open to SQL injection attacks. You'll want to use query parameters, not direct string concatenation. While it may look like you're just putting values into the query string, you're actually taking user input and treating it as executable code in your query string, which means users can run any arbitrary code they want on your database.
First, add parameters to your query:
"Insert INTO lr.users (upIme,geslo) VALUES (#upIme, #geslo)"
(You'll notice this also makes the query a heck of a lot cleaner and easier to read.) Then add your parameters to the command:
dataCommand.Parameters.AddWithValue("#upIme", this.tB_upIme.Text);
dataCommand.Parameters.AddWithValue("#geslo", this.tB_geslo.Text);
Then when you execute that command it will treat the user-input values as values instead of as executable code.
Change to single quotes ' in the values.
dataCommand.CommandText =
"Insert INTO lr.users (upIme,geslo)
VALUES ('"+this.tB_upIme.Text+"','"+this.tB_geslo.Text+"');";

Using C# to connect and insert to SQL Server 2012

I'm working on some code to try and get my array that's entered by the user to connect and send to SQL Server 2012. I've been told to use all of these commands to connect to the database.
One of my issues is that I've been looking through Stack Overflow and everyone suggests using parameters instead of concatenating to avoid SQL injection, but this is for my class and we are only 2 weeks into C# so I don't think he's going to like it if I use parameters.
I think my try catch is wrong, the top half is filled with red lines and how do you use the INSERT command with a for loop?
protected void btnDisplay_Click(object sender, EventArgs e)
{
//try
//{
// System.Data.SqlClient.SqlConnection varname1 = new System.Data.SqlClient.SqlConnection();
// varname1 = "server = LOCALHOST"; Database = Lab1; Trusted_connection = yes;
// varname1.Open();
// System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
// cmd.Connection = conn;
// cmd.CommandText = "Delete From Student";
// cmd.ExecuteNonQuery();
//
string sql = null;
for(int i=0; counter1 >= i; i++)
{
sql += "INSERT into Student VALUES(" + StudentId + Name + Address);
}
varname1.Close();
//}
catch (SqlException ex)
{
MessageBox.Show("Database failed" + ex.Message);
}
}
So, there are quite a few problems with this code. It might be best to spend another hour on it or so, then post any specific questions you can't figure out. Let me give you a few quick pointers though.
You have a catch() block, but the matching try block is commented out. This will result in a compiler error. It looks like you were just debugging some stuff, so no big deal. However, it's usually wise to post the actual code you're trying to run.
You're initializing a string to null, but you're concatenating on to the end. This will result in a runtime error. You should initialize your string to String.Empty instead. Also, look into the StringBuilder class if you're doing large amounts of string concatenation, as it's much faster.
You're (in theory) building a SQL string, but never actually running it anywhere. Nor do you return the value to anything that could run it.
Your INSERT statement isn't even valid. You don't have a matching end ) in the INSERT statement, and you have a rogue ) after your variables, which will result in a compiler error. You also just mash all the variables together, without quotes or commas between them. You probably want something more like:
sql += String.Format("INSERT into Student VALUES('{0}', '{1}', '{2}');", StudentId, Name, Address);
Use parameterized queries. Always. Who cares what your teacher says. If you don't, at the very least, check the strings for apostrophes first, as these will screw up your SQL statement by prematurely ending the string.
Your loop doesn't seem to make much sense. What is counter1? What value does it have? Even if it's set to a positive value, all you're doing is building the same SQL string over and over again since the values within the loop don't change. It's not clear what you're trying to do here.
You're calling varname1.Close(); but you've commented out the declaration of varname1, which will result in a compiler error.
Hope this helps!
Is this what you are after. You may have to adapt some of it. Sorry if it doesent fully work dont have a debugger at the moment.
class Data {
public int StudentId {get;set;}
public string Name {get;set;}
public string Address {get;set;}
}
protected void btnDisplay_Click(object sender, EventArgs e)
{
var datas = new List<Data>();
try
{
StringBuilder sql = new StringBuilder();
foreach(data in datas)
{
sql.Append(String.Format("INSERT into Student VALUES({0},'{1}','{2}') ",data.UserId,data.Name,data.Address));
}
var sqlConnection = new SqlConnection(#"Data Source=LOCALHOST;Initial Catalog=Lab1;Trusted_Connection=True;");
sqlConnection.Open();
var command = new SqlCommand(sql.ToString(),sqlConnection);
command..ExecuteNonQuery();
sqlConnection.Close();
}
catch(SqlException ex){
MessageBox.Show("Database failed" + ex.Message);
}
}

Categories