System.IndexOutOfRangeException SQL Server Query in C# - c#

I want to use selected item from my combo box for my SqlDataReader.
Which wrong in my syntax?
string varfunction = cbFunctionClass.SelectedItem.ToString();
con.Open();
SqlCommand sqlFunName = new SqlCommand("SELECT " + varfunction + " FROM sdn_cd_allclass WHERE MIDCLASS_CODE = '" + cbMiddleClass.Text + "'", con);
SqlDataReader sqlFunNameReader = sqlFunName.ExecuteReader();
while (sqlFunNameReader.Read())
{ lbFunctionClassName.Text = sqlFunNameReader[varfunction].ToString(); }
sqlFunNameReader.Close();
con.Close();
I need to use varfunction to select SQL column.

If varfunction contains a single digit, your query would read something like
SELECT 7 FROM sdn_cd_allclass...
for example. This would not select a column named 7 but the literal 7, i.e. an integer with the value of 7. And the column in the result, that holds this integer has no name, especially isn't its name 7.
If you want to select a column named 7 (which probably isn't the best idea BTW) you have to quote it by putting square brackets around it, so that the query becomes
SELECT [7] FROM sdn_cd_allclass...
So try
... "SELECT [" + varfunction + "] FROM sdn_cd_allclass..." ...
And as an aside, like already commented many times, I also recommend you to rework this and use parameterized queries (for the literals, i.e. the value in the WHERE clause of your current query, it won't work with identifiers, i.e. the column name).

Related

How to fix "System.Data.OleDb.OleDbException: 'Syntax error in UPDATE statement.'"?

I have been getting a syntax error in my UPDATE datagridview code which happens to work in another .cs file. My group has been looking at different solutions online but everything won't work.
My group has been looking at different solutions online but everything won't seem to work.
{
connection.Open();
OleDbCommand cmd = connection.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "Update Table1 set treatment = '" + treat.Text + "', remarks = '" + appRemarks.Text + "', cost = '" + treatCost.Text + "', Time = '" + textBox2.Text + "' where lastName = '" + Lastname.Text + "' ";
cmd.ExecuteNonQuery();
connection.Close();
MessageBox.Show("Updated Successfully!");
}
The expected output should be Updated Successfully! and it should reflect in the database file after clicking the update button. Sometimes the output is "Microsoft Engine database" which does not save the changes.
The error says "System.Data.OleDb.OleDbException: 'Syntax error in UPDATE statement.'" pointing to cmd.ExecuteNonQuery();
First, never use string concatenation to build a query. You're asking for a SQL Injection attack. The biggest thing I could see here is make sure that only columns that are string columns (varchar, char, text, etc..) have single-quoted values. Is cost a number? If so then it should be:
, cost=" + treatCost.Text + ",
If cost is a number, also make sure that there isn't a currency amount in the input field. If someone puts in 1,422.00 it's not a number and will fail since , is for decoration.
If someone puts in $1422.00 it's not a number as $ is for decoration.
Either of these would fail the query.
This would happen if someone types an apostrophe into the remarks field, which SQL server will interpret as the ending quote of the string. But much worse things can happen if the user knows a bit of sql and wants to cause trouble. For example, putting '-- in the remarks will result in
Update Table1 set treatment = 'blah', remarks = ''-- where lastName = 'foobar'
which will overwrite every row in the table, not only the one containing foobar.
Use query parameters so that user-provided values can't be interpreted as query keywords and structure.
Instead of remarks = '" + appRemarks.Text + "' you will have remarks = #Remarks as well as
cmd.Parameters.Add("#Remarks", SqlDbType.NText).Value = appRemarks.Text;
and all the other user inputs likewise.

MySQL Query Returns Parameter Column Name [duplicate]

This question already has answers here:
How to pass a table as parameter to MySqlCommand?
(2 answers)
Closed 6 years ago.
I am working in C# and MySQl in VS2015 to query my database and return a the information in a VARCHAR type column titled "method". However, the query returns the string "method", and not the values of the method column.
below is the code:
string queryOne = "SELECT " + "#columnName" + " FROM log.transactions";
MySqlCommand cmdOne = new MySqlCommand(queryOne, connectionString);
cmdOne.Parameters.AddWithValue("#columnName", "method");
MySqlDataReader dataReaderOne = cmdOne.ExecuteReader();
while (dataReaderOne.Read())
{
Console.WriteLine(dataReaderOne.GetString(0));
}
dataReaderOne.Close();
While this is the output:
method
method
method
.
.
.
.. for the number of rows in the method column. Is this a formatting problem? Is it possible that the configuration of my database is preventing VarChar's from returning correctly? When I change the query to query a column of type INT, it returns the correct values for an INT type column.
You can't parameterize a column name in a select statment. What you're doing is exaclty like saying select 'foo' from log.transactions. It selects the string 'foo' once for each row. You're just sticking a string value in there; it's not parsing the string value as SQL.
What you can do (if you can afford it) is select * from log.transactions, then your C# code can grab the data in whatever column the caller passed you the name of. With a lot of rows you could be dragging a lot of useless junk back from the DB though.
What you want in the code you show, though is just this:
string queryOne = "SELECT method FROM log.transactions";
If you really want to parameterize "method", that's sketchy because of SQL injection vulnerabilities.
string queryOne = "SELECT " + fieldname + " FROM log.transactions";
That looks good until some comedian using your application gives you a value of "0; drop table log.transactions;--" in the textbox. Then you've got troubles. If you ever concatenate a string variable into a SQL string that you're going to execute, you've got to be fanatical about sanitizing it, and even then you want to avoid it any way you can. It's Russian roulette.
Your query formation has to be like if you want to keep your column dynamic.Now pass column name accordingly.
string queryOne = "SELECT " + column_name + " FROM log.transactions";
MySqlCommand cmdOne = new MySqlCommand(queryOne, connectionString);
MySqlDataReader dataReaderOne = cmdOne.ExecuteReader();
while (dataReaderOne.Read())
{
Console.WriteLine(dataReaderOne[column_name]);
}
dataReaderOne.Close();

How to remove the double quotes variable in c#

My project has different SQL Server DataTable. I will bind the data from user request table. so got table name as
Example:
table = "MyTable"
How to write the SQL query for select the particular table.
con.open();
SqlAdaptor da = new SqlAdaptor ("select * from '" + table.replace(""", "\"")" + '")
cmd.ExecuteNonQuery();
My replace is not working so I hope to any one resolve my issue.
Just escape " character?1
table.Replace("\"", string.Empty);
Also you don't need single quotes for your table name. By the way if you get this table as an input, I will strongly suggest do some strong validation before you put it in your query or use a whitelist.
You didn't show us rest of your code but use using statement to dispose your connection and adapter objects.
1: Since it is an escape sequence character
You can also try
SqlAdaptor da = new SqlAdaptor ("Select * from " + table.Replace('"', ' ').Trim());
string table = "MyTable";
table.Replace('\"', ' '); //Or
table.Replace('\"',string.Empty);

put SELECT COUNT(*) statement result into int variable

I have a SELECT COUNT(*) statement in C#/ASP.NET and I want to store the result as an int to use as an IF condition. However I am getting an error in visual studio:
Error:System.Data.SqlClient.SqlException (0x80131904): The data types text and varchar are incompatible in the equal to operator. at System.Data.SqlClient.SqlConnection.
It tells me its occurring at the int temp line. The columns I'm accessing in the database table are of text type.
conn.Open();
String checkEmail = "select count(*) from Players where PlayerEmail= '" + txtEmailLogIn.Text + "'";
SqlCommand com = new SqlCommand(checkEmail, conn);
int temp = Convert.ToInt32(com.ExecuteScalar().ToString());
conn.Close();
if (temp > 0)
{
}
The problem is in your SQL. You can't use = when comparing TEXT data types, instead you can use LIKE:
String checkEmail = "select count(*) from Players where PlayerEmail LIKE '" + txtEmailLogIn.Text + "'";
Be warned though, that you are opening yourself up to SQL injection attacks when composing SQL strings like this.
DavidG's answer above works. However, if you have the opportunity to change the database schema, you could also fix the error by changing the PlayerEmail column from text to varchar(max). The text data type has been deprecated since at least 2005.

Can this select query be optimized more on a mobile device?

We have a C# mobile application with SQLite database.
We are having a larger inventory database, such as 30k or 100k items. The database file is 12MB on a flash memory card.
Running a simpler SELECT query with limit takes 10-15 seconds.
select id,invitem,invid,cost from inventory
where itemtype = 1 and
(invitem like '%5204d%' or invid like '%5204d%')
limit 25
sometimes a category is involved too,
select id,invitem,invid,cost from inventory
where itemtype = 1 and
categoryid=147 and
(invitem like '%5204d%' or invid like '%5204d%')
limit 25
Indexes are created on:
cmd.CommandText = "CREATE INDEX IF NOT EXISTS idx_inventory_categoryid ON " + this.TableName + " (categoryid);";
cmd.ExecuteNonQuery();
cmd.CommandText = "CREATE INDEX IF NOT EXISTS idx_inventory_itemtype ON " + this.TableName + " (itemtype);";
cmd.ExecuteNonQuery();
cmd.CommandText = "CREATE INDEX IF NOT EXISTS idx_inventory_invitem ON " + this.TableName + " (invitem);";
cmd.ExecuteNonQuery();
Those two fields in Like are VARCHAR, the others are NUMERIC.
Can this select query be optimized more on a mobile device?
The problem is the initial % in your where..like clause. The index cannot be used in theis query, so a table scan is the only way it can be done. Adding the category id will help - at least it can use that inxdex.
You can use EXPLAIN to check whether the indices are actually used. I would guess that the wildcard at the beginning of like '%5204d%' disables any use of indices on invitem.

Categories

Resources