After I try to output the password in the dataGrid, from the given Username in the txt_Username textbox, I get this error message:
MySql.Data.MySqlClient.MySqlException: "Unknown column 'Test' in 'where clause'"
MySqlDataAdapter da = new MySqlDataAdapter("Select Password from tbl_anmeldedaten Where Username=" + txt_Username.Text, con);
da.SelectCommand.CommandType = CommandType.Text;
DataTable dt = new DataTable();
da.Fill(dt);
dataGridView1.DataSource = dt;
The exact cause of the error is that you are trying to execute the following query:
SELECT Password
FROM tbl_anmeldedaten
WHERE Username = Test;
Does it look like Test should have single quotes around it? Yes, it should, and you could add that to your raw query. But, concatenating a query like this in C# leaves open the possibility for SQL injection. A much better approach is to use prepared statements:
string sql = "SELECT Password FROM tbl_anmeldedaten WHERE Username = #val1";
MySqlCommand cmd = new MySqlCommand(sql, MySqlConn.conn);
cmd.Parameters.AddWithValue("#val1", txt_Username.Text);
cmd.Prepare();
MySqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
// consume a record in the result set
}
You are using string concatenation which is a vector for SQL injection attacks. Perhaps the username in the text field is doing some SQL which it shouldn't be allowed to (for instance '' OR Test=1. There are plenty of resources on using parameterized queries which should remedy the problem.
Related
I'm making an application where we can see data from my database in a datagridview. I got to a point that I need to filter somethings and I'm only able to filter with "numbers" for example (IdProducts), this is the code I'm using:
string query= "SELECT * FROM alunos where Estado="+textBox1.Text;
if(a.open_connection() == true)
{
MySqlCommand cmd = new MySqlCommand(query, a.connection);
MySqlDataReader dataReader= cmd.ExecuteReader();
if(dataReader.HasRows)
{
DataTable dt= new DataTable();
dt.Load(dataReader);
dataGridView1.DataSource= dt;
}
dataReader.Close();
a.close_connection();
}
in this code I'm trying to filter the column "Estado" which is text and it gives me this error,
Unknown column 'A' in 'where clause'
"A" is what I'm trying to filter (is a camp from Estado column)
My question is how can I be able to filter with not only numbers but text too?
string query= "SELECT * FROM alunos where Estado="+textBox1.Text;
if(a.open_connection() == true)
{
MySqlCommand cmd = new MySqlCommand(query, a.connection);
MySqlDataReader dataReader= cmd.ExecuteReader();
if(dataReader.HasRows)
{
DataTable dt= new DataTable();
dt.Load(dataReader);
dataGridView1.DataSource= dt;
}
dataReader.Close();
a.close_connection();
}
Yuo need to change your code to use a parameterized query like this
string query= "SELECT * FROM alunos where Estado=#state";
if(a.open_connection() == true)
{
MySqlCommand cmd = new MySqlCommand(query, a.connection);
cmd.Parameters.Add("#state", MySqlDbType.VarChar).Value = textBox1.Text;
MySqlDataReader dataReader= cmd.ExecuteReader();
if(dataReader.HasRows)
{
DataTable dt= new DataTable();
dt.Load(dataReader);
dataGridView1.DataSource= dt;
}
dataReader.Close();
a.close_connection();
}
The problem in your original code is caused by the fact that you concatenate the string value from the textbox without adding quotes around it. In this way the parser is fooled and thinks that you are naming a field and, of course, cannot find it.
However, "resolving" the problem simply adding single quotes around the textbox is not a real solution because you are opening your code to Sql Injection attacks. Instead, if you use a parameterized queries, you don't have your original problem, you avoid sql injection, you will not face other 'syntax errors' caused by the presence of single quotes in your textbox.text property and your database engine can optimize the query because parsing it just one time even if you call it more than one time.
I am using an Informix db, and I am trying to get data for a specific item and store it in a datatable.
I checked the following:
1) connection string looks good
2) the connection is able to open
3) I used the same connection string from the web.config on a dataset creating a table adapter and it is able to retrieve the record.
This is the code I am using:
var connectionstring = ConfigurationManager.ConnectionStrings["TestDataTable"].ConnectionString;
OdbcConnection con = new OdbcConnection(connectionstring);
//con.ConnectionString = connectionstring;
if (TxtItem.Text != hold_item)
{
con.Open();
OdbcCommand cmd = new OdbcCommand(#"Select t_item,t_idsc,t_upct,
t_item_upc,t_ctyp,t_citg,
t_best,t_disp,t_mold,t_csel
from informix.tsckcm907
where t_item = " + stitem, con);
OdbcDataReader myReader = cmd.ExecuteReader();
DataTable testdt = new DataTable();
testdt.Load(myReader);
foreach (DataRow row in testdt.Rows)
{
lbldesc.Text = row["t_idsc"].ToString();
Spanish_Item();
{
DropDownList2.SelectedIndex = 1;
object stlanguage = 1;
hold_language = Convert.ToString(stlanguage);
TxtBestBefore.Text = row["t_best"].ToString();
holdbest = Convert.ToInt16(TxtBestBefore.Text);
}
}
myReader.Close();
myReader.Dispose();
cmd.Dispose();
con.Close();
con.Dispose();
}
in debug mode my error occurs at the OdbcDataReader line:
error message:
An exception of type 'System.Data.Odbc.OdbcException'
occurred in System.Data.dll but was not handled in user code
Additional information: ERROR [42000] [Informix]
[Informix ODBC Driver][Informix]A syntax error has
occurred.
If your Informix ODBC driver says: "A syntax error has occurred" then you have to check your SQL statement:
"Select t_item,... from informix.tsckcm907 where t_item = " + stitem
I think that something is wrong with stitem. We don't know what type and value it is, but if its type is some kind of string or date then it may be in the wrong form. Easiest way is to extract full SQL statement (simply print it before execution) and use it with some database editor (for example db_access from Informix). Then make it work in SQL editor and transform stitem variable into acceptable form (add quotes, escape internal quotes, escape special characters etc.)
I also recommend use of PreparedStatement that separates your query from data. This way you do not need to worry about stitem form. No quotes, no escaping, just place holder in query string and value added separately.
I don't use C# but I see that C# can work with preapred statements with unnamed parameters:
cmd.CommandText = "SELECT ... FROM ... WHERE t_item = ?";
cmd.Parameters.Add("#t_item", ObdcType.VarChar, 200).Value = t_item;
or with named parameters:
cmd.CommandText = "SELECT ... FROM ... WHERE t_item = #t_item";
cmd.Parameters.Add("#t_item", ObdcType.VarChar, 200).Value = t_item;
I use unnamed parameters from ODBC so Informix driver can work with such parameters but you will have to check it yourself with C#.
I was wondering if it is possible for the update button to save the changes made in the table. I wrote this code but I have no idea how it could possibly work
This is the code i wrote for the update button:
string conString = "Data Source=MIRANDA-PC;Initial Catalog=Futebol do Rosa;Integrated Security=True";
SqlConnection con = new SqlConnection(conString);
string selectSql = "Update Players$ set Player Name='" + dataGridView2.Text + "";
SqlCommand cmd = new SqlCommand(selectSql, con);
con.Open();
This is the table I want to update the values in:
Well, you just need to execute your query with ExecuteNonQuery.
But more important, you should always use parameterized queries. This kind of string concatenations are open for SQL Injection attacks.
Also use using statement to dispose your SqlConnection and SqlCommand.
And if your table or column names more than one word, you need to use them with [] as [Player Name]. And honestly, it is a little bit weird to use $ sign in a table name.
using(SqlConnection con = new SqlConnection(conString))
using(SqlCommand cmd = con.CreateCommand())
{
cmd.CommandText = "Update Players$ set [Player Name] = #name";
cmd.Parameters.Add("#name", SqlDbType.NVarChar, 16).Value = dataGridView2.Text;
con.Open();
cmd.ExecuteNonQuery();
}
You have to execute your SQL query with your db object.
dbinstance.ExecuteSqlCommand(string sqlcommand, object[] params);
This method is both for DDL and DML.
you can also use ExecuteNonQuery method.
cmd.CommandText = "Update Players$ set [Player Name] = #Playername";
cmd.Parameters.Add("#Playername", SqlDbType.NVarChar, 16).Value = dataGridView2.Text;
con.Open();
cmd.ExecuteNonQuery();
The best solution (if possible) to to convert your DAL (Data Access Layer) to Entity-framework based, instead of writing your own SQL queries. This is safe-by-design and never is vulnerable to SQL Injection of any kind.
Here is some mockup code:
using (AppEntities currDb = new AppEntities)
{
Players PlayerToEdit =
from player in currDb.Players
where player.PlayerID == lngPlayerID
select player.First();
PlayerToEdit.PlayerName = dataGridView2.Text;
currDb.SaveChanges();
}
You can read about it some more here:
https://msdn.microsoft.com/en-us/data/ef.aspx
C# visual studio 2012 professional asp.net
I have a table containing usernames: Josh, Jeremy, Jared, Justin...
And I created a web page gridview that shows the entire table but I only want it to show Justin and nothing else.
How do I do this?
Here's some code that didn't work:
SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True");
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
SqlDataReader rs;
con.Open();
SqlParameter uName = new SqlParameter("paramFName", Account.Text);
cmd.Parameters.Add(uName);
cmd.CommandText = "SELECT * FROM Transactions WHERE FName=#paramFName";
rs = cmd.ExecuteReader();
cmd.Parameters.Clear();
rs.Close();
Am I supposed to create a view of the table? I tried but wasn't successful.
tips?
You simply missed the "#" at the parameter name:
SqlParameter uName = new SqlParameter("#paramFName", Account.Text);
In case of your where-clause this has the effect that you didn't provide anything for the specified parameter which simply let the query provider ignore this condition, which results in the effective query SELECT * FROM Transactions.
Beside you should think about using the using block:
using (SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\Database1.mdf;Integrated Security=True"))
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = con;
cmd.CommandText = "SELECT * FROM Transactions WHERE FName=#paramFName";
cmd.Parameters.AddWithValue("#paramFName", Account.Text);
con.Open();
using (var rs = cmd.ExecuteReader())
{
//ToDo: Do something with the reader.
}
}
And another hint: If you need to fill up a DataTable with the result, you can use a SqlDataAdapter instead of using the data reader:
using (var adapter = new SqlDataAdapter(cmd))
{
var dataTable = new DataTable();
dataTable.TableName = "QueryResult";
adapter.Fill(dataTable);
return dataTable;
}
If you are trying to select the first 10 names for example then you need to change your SQL Select to the following:
cmd.CommandText = "SELECT TOP 10 * FROM Transactions WHERE FName=#paramFName";
Is that what you were after?
EDIT
OK so you are not actually displaying your data anywhere which is the actual problem.
You need to create a datatable and display it in a gridview.
Check out the following links for examples:
Gridview examples
MSDN Gridview examples
Your code seems fine, although you do not provide much information.
If you're using SQL Server 2012 have a look at the keywords OFFSET and FETCH.
For earlier versions you need to use ROW_NUMBER OVER PARTITION
As a good practice you should always limit the number of elements returned.
I'm working with C# and SQL Sever 2008, when I try to create a command for searching a record I got exception that said "Invalid Column name"
this is my code :
void cari()
{
koneksi.Open();
DataTable dt = new DataTable();
SqlDataAdapter SDA = new SqlDataAdapter("SELECT * FROM jadwalkuliah where Subject = "+ textBox1.Text, koneksi);
SDA.Fill(dt);
koneksi.Close();
dataGridView1.DataSource = dt;
}`
the search command should be work as search engine, can anyone help me?
Well the immediate problem is that your WHERE clause will look something like:
where Subject = Foo
which is trying to compare the value of the Subject column with the value of the Foo column.
The hacky way of fixing this is to put quotes round the value. The better solution is to use parameterized SQL:
string sql = "SELECT * FROM jadwalkuliah where Subject = #Subject";
using (SqlConnection connection = new SqlConnection(...))
using (SqlDataAdapter adapter = new SqlDataAdapter(sql, connection))
{
connection.Open();
adapter.SelectCommand.Parameters.Add("#Subject", SqlDbType.VarChar)
.Value = textBox1.Text;
adapter.Fill(dt);
}
Additionally, note that you shouldn't be performing database accesses from a GUI thread. It's not clear whether this is a web app (in which case it's okay) or WPF/WinForms (in which case it's not).
Note that that will still try to make an exact match. For a "wildcard" match you'll need to change it to something like:
SELECT * FROM jadwalkuliah where Subject LIKE #Subject
... and add the parameter with something like "%" + textBox1.Text + "%". (You'll need to then think about escaping within that value, but that's another matter...)
You haven't quoted the value of subject:
SqlDataAdapter SDA = new SqlDataAdapter("SELECT * FROM jadwalkuliah where Subject = '"+ textBox1.Text + "'",
koneksi);
Or for a contains search:
SqlDataAdapter SDA = new SqlDataAdapter("SELECT * FROM jadwalkuliah where Subject = '%"+ textBox1.Text + "%'", koneksi);
You shouldn't build queries this way. It is susceptible to SQL injection attacks.