is this the correct statement if not plz help me correct it.
String query = "delete from favourite where username=" +
Session["username"].ToString() + "and id=" + id;
If your question is purely about SQL, then yes, what you have will work. But, as you have it, you have a very serious security problem. Google "SQL injection attacks". I'm not sure what you are using for data access (ADO.NET? Entiry Framework? Dapper?) But regardless, you'll want to use parameters:
var sql = "delete from favourite where username=#username and id=#id";
and then:
cmd.Parameters.AddWithValue("#username", Session["username"].ToString());
cmd.Parameters.AddWithValue("#id", id);
But even then, AddWithValue isn't the best way, because it can cause type conversion issues once the query hits the database. You are better off doing it longhand:
var userNameParam = new SqlParameter("username", SqlDbType.VarChar);
userNameParam.Value = Session["username"].ToString();
var idParam = new SqlParameter("id", SqlDbType.Int);
idParam .Value = id;
command.Parameters.Add(salaryParam);
command.Parameters.Add(idParam );
Related
This is the error message
MySql.Data.MySqlClient.MySqlException: 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '''')' at line 1'
this is my query
MySqlCommand cmd = new MySqlCommand("insert into subject(id, code, title, unit) values('" + textBox1.Text + "',''" + textBox2.Text + "',''" + textBox3.Text + "',''" + textBox4.Text + "')", conn);
I've been looking over at it for over an hour now and I still get this error.
It is recommended to use Parameterized Query.
UPDATED: As suggested by #CodeCaster for the concerns mentioned in Stop Using AddWithValue() article, I switch all the AddWithValue() to Add("#Parameter", SqlDbType).Value.
MySqlCommand cmd = new MySqlCommand("insert into subject(id, code, title, unit) values(#ID, #Code, #Title, #Unit)", conn);
cmd.Parameters.Add("#ID", SqlDbType.int).Value = textBox1.Text;
cmd.Parameters.Add("#Code", SqlDbType.Varchar, 10).Value = textBox2.Text;
cmd.Parameters.Add("#Title", SqlDbType.NVarchar, 50).Value = textBox3.Text;
cmd.Parameters.Add("#Unit", SqlDbType.Varchar).Value = textBox4.Text;
And also be sure that the value you pass with the SqlDbType must match the data type as respective database table column.
The reasons to use Parameterized Query are:
It simplifies the query in passing the parameters and makes the query become more readable.
Prevent SQL Injection.
Reference: Prepare MySQL Statement
I am implementing a login form using C# and MySQL, The user should enter his/her username and password then select if he/she is a student, instructor or admin.
then I want to check if entered values are correct , here is my code:
connection.Open();
MySqlCommand cmd = new MySqlCommand();
cmd.CommandText = "Select * from #userType where username=#user and password=#pass";
cmd.Parameters.AddWithValue("#userType", userType);
cmd.Parameters.AddWithValue("#user", user);
cmd.Parameters.AddWithValue("#pass", pass);
cmd.Connection = connection;
MySqlDataReader login = cmd.ExecuteReader();
But the query didn't work !
the error message :
MySql.Data.MySqlClient.MySqlException, HResult=0x80004005,
Message=You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near ''student' where username='noor123' and password='123456'' at
line Source=MySql.Data
what is the error ?
The SQL query generated by that code is:
Select * from 'student' where username="noor123" and password="123456"
The table can't be inside '' as that's not correct SQL syntax.
You can't use the parameter for the table name, do this instead, this way you won't get '' for the table name:
connection.Open();
MySqlCommand cmd = new MySqlCommand();
cmd.CommandText = "Select * from " + userType.ToString() + " where username=#user and password=#pass";
cmd.Parameters.AddWithValue("#user", user);
cmd.Parameters.AddWithValue("#pass", pass);
cmd.Connection = connection;
MySqlDataReader login = cmd.ExecuteReader();
If this is just an assignment and not a real-world program then do the following.
Make sure variables userType, user and pass are of type String.
Make sure that userType represents a syntactically correct table or view name.
Update this line cmd.CommandText = $"Select * from {userType} where username=#user and password=#pass";
Remove this line cmd.Parameters.AddWithValue("#userType", userType);
I believe that should help. I didn't check myself.
However in real world you shouldn't program it this way. There are many security considerations when dealing with authentication/authorization not mentioning the possibility for sql injection. If this is a real project then I recommend you to read appropriate materials regarding the subject.
What's the safest way of generating SQL queries in C#, including cleansing user input so it's safe from injection? I'm looking to use a simple solution that doesn't need external libraries.
Use Sql Parameters:
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlparameter(v=vs.80).aspx
Here's an example in C#
SqlCommand tCommand = new SqlCommand();
tCommand.Connection = new SqlConnection("YourConnectionString");
tCommand.CommandText = "UPDATE players SET name = #name, score = #score, active = #active WHERE jerseyNum = #jerseyNum";
tCommand.Parameters.Add(new SqlParameter("#name", System.Data.SqlDbType.VarChar).Value = "Smith, Steve");
tCommand.Parameters.Add(new SqlParameter("#score", System.Data.SqlDbType.Int).Value = "42");
tCommand.Parameters.Add(new SqlParameter("#active", System.Data.SqlDbType.Bit).Value = true);
tCommand.Parameters.Add(new SqlParameter("#jerseyNum", System.Data.SqlDbType.Int).Value = "99");
tCommand.ExecuteNonQuery();
In essence don't do this
SqlCommand command = new SqlCommand(MyConnection);
command.CommandText = "Select * From MyTable Where MyColumn = '" + TextBox1.Text + "'"
...
do
SqlCommand command = new SqlCommand(MyConnection);
command.CommandText = "Select * From MyTable Where MyColumn = #MyValue";
command.Parameters.AddWithValue("MyValue",TextBox1.Text);
...
Basically never build your sql command directly from user input.
If you use an ORM, such as EntityFrameworks / POCO all queries are done in the latter form.
The first rule of thumb is to make sure you use parameterized queries/commands. Basically don't dynamically build a sql string that includes something that the user has input into the page.
If you use on ORM (EF, L2S, Nhib), this is typically handled in most cases because most all of them run parameterized queries.
Parametrize your queries.
In case if you build some TSQL which builds some other dynamic TSQL - then use some described technique
What does "parametrizing means?
See, not use something like this:
sqlCommand.CommandText = "select * from mytable where id = "+someVariable;
use this:
sqlCommand.CommandText = "select * from mytable where id = #id";
sqlCommand.Parameters.AddWithValue("#id", someVariable);
Make use of Parametrized Queries.
Simple Example.
var sql = "SELECT * FROM MyTable WHERE MyColumn = #Param1";
using (var connection = new SqlConnection("..."))
using (var command = new SqlCommand(sql, connection))
{
command.Parameters.AddWithValue("#Param1", param1Value);
return command.ExecuteReader();
}
More Detailed Example.
protected void btnGoodAddShipper_Click(object sender, EventArgs e)
{
string connStr = c
"Server=(local);Database=Northwind;Integrated Security=SSPI";
// this is good because all input becomes a
// parameter and not part of the SQL statement
string cmdStr =
"insert into Shippers (CompanyName, Phone) values (" +
"#CompanyName, #Phone)";
using (SqlConnection conn = new SqlConnection(connStr))
using (SqlCommand cmd = new SqlCommand(cmdStr, conn))
{
// add parameters
cmd.Parameters.AddWithValue
("#CompanyName", txtCompanyName.Text);
cmd.Parameters.AddWithValue("#Phone", txtPhone.Text);
conn.Open();
cmd.ExecuteNonQuery();
}
}
Using DBML and LINQ to handle it for you. Many people have worked on those to ensure those issues are well mitigated.
And if not than at least parametrize your queries.
A proper name for DBML is linq2sql or an advanced version is called entity framework. These technologies are provided by Microsoft and well integrated with visual studio. Does not require additional libraries.
Pretty stable products..
My current best code is:
string delNonQuery = "DELETE FROM " + Settings.DataSource + " WHERE #keycolumn=#keyuid";
SqlCommand cmd = new SqlCommand(delNonQuery,readerConn);
SqlParameter kc = new SqlParameter("keycolumn", SqlDbType.VarChar);
SqlParameter key = new SqlParameter("keyuid", SqlDbType.VarChar);
cmd.Parameters.Add(kc).Value = Settings.KeyColumn;
cmd.Parameters.Add(key).Value = Page.Request["key"].ToString().Trim();
readerConn.Open();
cmd.ExecuteScalar();
readerConn.Close();
This executes but affects a whopping zero rows. If I change the SqlDbType on keyuid to UniqueIdentifier it just ends up with me getting a dozen variations on "failed to convert character string into uniqueidentifier". I have to use a parameterized query for data cleanliness, I'm just really stuck as to how...
You can't specify a parameter for a column name - you need to concatenate it the same way you do for the table name.
This:
"DELETE FROM " + Settings.DataSource + " WHERE #keycolumn=#keyuid"
Should change to:
"DELETE FROM " + Settings.DataSource + " WHERE " + Settings.KeyColumn + " =#keyuid"
Though I would probably write it as:
string delNonQuery = string.Format("DELETE FROM {0} WHERE {1} = #keyuid",
Settings.DataSource,
Settings.KeyColumn);
For completeness sake, I will mention that this is open to SQL injection. You need to make sure your Settings values are clean.
I don't think you can parameterise the column name ("keycolumn")
Try this:
string delNonQuery = string.Format("DELETE FROM " + Settings.DataSource + " WHERE {0}=#keyuid", Settings.KeyColumn);
SqlCommand cmd = new SqlCommand(delNonQuery,readerConn);
SqlParameter key = new SqlParameter("keyuid", SqlDbType.VarChar);
cmd.Parameters.Add(key).Value = Page.Request["key"].ToString().Trim();
readerConn.Open();
cmd.ExecuteScalar();
readerConn.Close();
Usual warnings apply regarding concatanating strings to build SQL; this is likely a security risk.
The best method might be to encapsulate your SQL in a stored procedure, pass the column name and value as parameters and then execute using dynamic SQL.
You need to convert the string to GUID:
Relevant Lines:
SqlParameter key = new SqlParameter("keyuid", SqlDbType.UniqueIdentifier);
...
cmd.Parameters.Add(key).Value = new Guid(Page.Request["key"].ToString().Trim());
Which only solves the GUID/UniqueIdentifer issue
Can someone let me know what is wrong with my SQL Statement and how I can improve it?
da = new SqlDataAdapter("SELECT * FROM Guests"+" WHERE Students.name='" +
byNametextBox.Text + "'", MyConn);
An EXISTS predicate is slightly more efficient than a JOIN if you want only columns from one of the tables. Additionaly - never inject strings into SQL statements like that - you're just begging for SQL Injection attacks, or related crashes errors (Yes, I know it's a Forms application, but the same holds true. If you're searching for a name like "O'Leary", you'll get a crash).
SqlCommand cmd = new SqlCommand("SELECT * FROM Guests WHERE EXISTS (SELECT Id FROM Students WHERE Guests.StudentId = Students.Id And Students.name= #name)", MyConn);
cmd.Parameters.Add("#name", SqlDbType.VarChar, 50).Value = byNametextBox.Text;
SqlDataAdapter adapt = new SqlDataAdapter(cmd);
Note: Some people may argue that "SELECT *" is bad, and that you should consider specifying individual column names
You need to worry about SQL Injection. Put simply, SQL Injection is when a user is able to put arbitrary SQL statements into your query. To get around this, either use a Stored Procedure or a Parametrized SQL Query. An Example of a Parametrized SQL query is below:
SqlConnection conn = null;
SqlDataReader reader = null;
//Connection string goes here
string studentName = byNametextBox.Text;
SqlCommand cmd = new SqlCommand(
"SELECT * FROM Guests "+" WHERE Students.name = #name", conn);
SqlParameter param = new SqlParameter("#name", SqlDbType.NVarChar, 50);
param.Value = studentName;
cmd.Parameters.Add(param);
reader = cmd.ExecuteReader();
//Do stuff with reader here
SqlDataAdapter("SELECT Guests.* FROM Guests,Students WHERE Guest.StudentId = Student.Id and Students.name='" + byNametextBox.Text + "'", MyConn);`
You need an Inner Join. I think it would be something like this:
SELECT Guests.* FROM Guests INNER JOIN Students ON Students.name = Guests.name WHERE Students.name = '" + byNametextBox.Text + "'"
Try it:
"SELECT g.*
FROM Guests g
INNER JOIN Students s ON g.StudentId = s.StudentId
WHERE Students.Name = '" + byNametextBox.Text + '"'
Assuming that the field wich relates both tables is StudentId.
Beware that SQL is not the same between different Servers. This statement will work on Sql Server, I don't know in others. Also, beware that you aren't protecting yourself on SQL Injection attacks. You should perform your query with parameters, instead of concatenating strings in the way you are doing it.
This is a simple query that you should know by yourself. You can search for tutorials on Google, but here is a generic introduction.