Else statement fails to work within a while loop - c#

Below is my code to connect to the database using MySqlDataReader. Now the if statement is working fine but the else statement doesnt. When i use the debug function in VS it kept skipping the else statement and jump to the reader.Close();.
Any idea. Thanks
private void db()
{
string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
MySqlConnection connection = new MySqlConnection(constr);
connection.Open();
MySqlCommand command = connection.CreateCommand();
command.CommandText = "SELECT * FROM user Where user_id ='" + Userid.Text + "'" + "And password='" + Password.Text + "'";
MySqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
if (!reader.IsDBNull(0))
{
Label1.Text = reader["user_id"].ToString();
}
else
{
Label1.Text = "nodata";
}
reader.Close();
}
}

First of all: Don't use string concatenation for building queries, but use parameterized queries!
As for your problem: I assume this query will only return either 1 or 0 rows, so you don't need the loop but just check
if (reader.Read()) {
//...
}
Using SELECT * with column indexes is potentially dangerous, because you may not know what the "first" column returned is. I would suggest name your desired columns in the query
SELECT user_id, user_name ... FROM ...
What is the value of the first column returned? I assume, it's the user_id. Thus, this can never fulfill the condition IsDBNull(0) because user_id is your matching criterion in the WHERE clause. If your WHERE clause does not match any record in the table, reader.Read() will already fail, so you'll never get to your else branch.
Furthermore, I would suggest a using clause, which will dispose the reader automatically, so you don't have to care about closing it.
command.CommandText = "SELECT user_id, foo, bar from user where user_id = #userid and password = #password";
command.Parameters.AddWithValue("#user_id", UserId.Text);
command.Parameters.AddWithValue("#password", Passowrd.Text);
using (MySqlDataReader reader = command.ExecuteReader()) {
if (reader.Read()) {
Label1.Text = reader["user_id"].ToString();
} else {
Label1.Text ="nodata";
}
}

Related

database INNER JOIN

These are the two set up tables
LOGIN TABLE
USER'S NAME
I want to create something like the User will key in their USER_ID and USER_PWD in a textbox. IF the user successfully login, it will say " HI + PATNAME ".
I have created this code so far but it isnt working.
string sqlStr = "Select patpro.'PATNAME' FROM patpro,useform where USER_ID=#name and USER_PWD=#password and useform.'USER_ID' = patpro.'USERID'";
cmd.Parameters.AddWithValue("#name", txtValue.Text);
cmd.Parameters.AddWithValue("#password", txtPassword.Password);
cmd.CommandText = sqlStr;
cmd.Connection = connection;
connection.Open();
MySqlDataReader login = cmd.ExecuteReader();
if (login.HasRows)
{
login.Read();
string name = (login["USER_ID"].ToString());
txtAssignID1.Text = "Login verified. Hi, " + name + "\n";
}
From what I see, you're trying to use login["USER_ID"].ToString() which USER_ID is a nonexistent column definition inside current SELECT statement. Hence, you should add column names which defined in SELECT results like login["PATNAME"] and use proper INNER JOIN statement instead:
string sqlStr = #"SELECT patpro.PATNAME FROM patpro INNER JOIN useform
ON useform.USER_ID = patpro.USERID
WHERE useform.USER_ID = #name AND useform.USER_PWD = #password";
cmd.Parameters.AddWithValue("#name", txtValue.Text);
cmd.Parameters.AddWithValue("#password", txtPassword.Password);
cmd.CommandText = sqlStr;
cmd.Connection = connection;
connection.Open();
MySqlDataReader login = cmd.ExecuteReader();
if (login.HasRows)
{
// read value inside the loop, because MySqlDataReader is forward-only
while (login.Read())
{
string name = login["PATNAME"].ToString();
txtAssignID1.Text = "Login verified. Hi, " + name + "\n";
}
}
Additional note: Better to use using statement for MySqlConnection, MySqlCommand and MySqlDataReader to ensure immediate disposal of MySQL connection objects after fetching query results.

sqlite - get a single column value - not working

I am using c# and I cannot get any vaue. The data returns null. This is my code.
SQLiteConnection DBConnection;
DBConnection = GetMyconnection();
DBConnection.Open();
string DBCommand = "SELECT * FROM settings WHERE setting_key = '" + setting_key + "' LIMIT 1";
using (SQLiteCommand sqlCommand = new SQLiteCommand(DBCommand, DBConnection))
{
using (SQLiteDataReader DBDataReader = sqlCommand.ExecuteReader())
{
if (DBDataReader.Read())
{
object data = sqlCommand.ExecuteScalar();
return DBDataReader.GetString(DBDataReader.GetOrdinal("setting_value"));
}
else
{
return "Error";
}
}
}
DBConnection.Close();
This code is placed in a global helper function which I call from a form.
Kindly help.
The main item is saw was that you were running an ExecuteScalar on the same command as the ExecuteReader and I could see no reason why. Other things I noted was that you were concatenating the statement instead of using parameters, you only needed one value but were using SELECT *, and there was no exception handling. I would have a Unique Index on the settingkey column to speed up the query and prevent duplicates, so you don't need to have the LIMIT 1 on the command
I rolled this up trying to use as much of your code as possible. I altered the SQL command to get the one value that you wanted, only using the ExecuteScalar method, and using the conditional operator instead of the if...then block. The actual command has been wrapped in a try...catch for exception handling and will provide error feedback
string ReturnValue;
SQLiteConnection DBConnection;
DBConnection = GetMyconnection();
DBConnection.Open();
string DBCommand = "SELECT setting_value FROM settings WHERE setting_key = #settingkey LIMIT 1";
using (SQLiteCommand sqlCommand = new SQLiteCommand(DBCommand, DBConnection)) {
sqlCommand.parameters.AddWithValue("#settingkey", setting_key);
try {
object data = sqlCommand.ExecuteScalar();
ReturnValue = (data != null) ? data.ToString() : "Error";
}
catch (Exception ex) { ReturnValue = "Exception: " + ex.Message; }
}
DBConnection.Close();
return ReturnValue;
this code read a list of row but if your query is ok work.
string sql = "SELECT * FROM settings WHERE setting_key = '" + setting_key + "' LIMIT 1";
SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);
SQLiteDataReader reader = command.ExecuteReader();
while (reader.Read())
Console.WriteLine("Name: " + reader["setting_value"] + "\tScore: " + reader["score"]);

SQL Invalid Column name detection from Query

I've tried running the code and I have no idea what's wrong with the query. Because it keeps saying invalid column name, when I'm trying to retrieve the data from that column instead. The column name matches the one in the DB. It's well connected because it's connected to a login form where it detects the other given password and name. I'm using based on a search textbox.
private void btnSearch_Click(object sender, EventArgs e)
{
SqlConnection cnn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyDetailConnectionString"].ToString());
try
{
cnn.Open();
SqlCommand command = new SqlCommand();
command.Connection = cnn;
string query = "SELECT *FROM AffiliatedRegister WHERE Username=" + txtUser.Text + "";
command.CommandText = query;
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
---[Converting String from db /Insert to textboxes]---
}
cnn.Close();
}
catch (Exception ex)
{
MessageBox.Show("Error" + ex);
}
}
You need to wrap the username text in quotes.
Your emitted sql script is gonna look like:
SELECT *FROM AffiliatedRegister WHERE Username=InputUserName
So SQL is trying to compare the column Username to the column InputUsername.
Once you wrap the user name in quotes, it would be:
SELECT *FROM AffiliatedRegister WHERE Username='InputUserName'
Your statement erred because you did not wrap your string in quotes so Sql interpeted it as on object and not a string. That being said there you should use parameters and not string concatenation.
Use parameters
Wrap your SqlConnection in a using block
You should specify the column order in the SELECT statement, do not use *.
Do not swallow an Exception unless you know how to recover from it
Update code
private void btnSearch_Click(object sender, EventArgs e)
{
// use ConnectionString property
// wrap in using block
using (SqlConnection cnn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyDetailConnectionString"].ConnectionString))
{
try
{
SqlCommand command = new SqlCommand();
command.Connection = cnn;
// use parameters
// avoid *, specify columns instead
string query = "SELECT * FROM AffiliatedRegister WHERE Username= #userName";
command.CommandText = query;
// use parameters, I assumed the parameter type and length - it should be updated to the type and length specified in your table schema
command.Parameters.Add(new SqlParameter("#userName", SqlDbType.VarChar, 200) {Value = txtUser.Text });
// open as late as possible
cnn.Open();
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
// ---[Converting String from db / Insert to textboxes]-- -
}
}
catch (Exception ex)
{
MessageBox.Show("Error" + ex);
// do not swallow the exception unless you know how to recover from it
throw;
}
}
}
Well first of all your query is very dangerous so please don't use it for production purpose.
Now what you need to do :-
In your query you need single quotes around the txtUser.Text.
Like this :-
"SELECT *FROM AffiliatedRegister WHERE Username='" + txtUser.Text
+ "'";
Resulting query : SELECT *FROM AffiliatedRegister WHERE Username = 'txtUser.Text';
You can also put double quotes like :-
...Username=\"" + txtUser.Text + "\"";
its complicated ;-) Earlier one is better for the reading purpose.
Why it did not run?
Because all values except integers must be passed inside single or double quotes in a query. Like :-
SELECT * FROM TABLE_NAME WHERE TABLE_NAME.COLUMN_NAME = "VALUE";
Now one very important thing please don't use these kinds of queries for production purpose. I guess you are in development phase so answering this question is not gonna ruin your life ...!!!
You can try to replace the your string: string query = "SELECT *FROM AffiliatedRegister WHERE Username=" + txtUser.Text + "";
to: string query = "SELECT <yourcolumn> FROM AffiliatedRegister WHERE Username=" + txtUser.Text + "";
I believe it is necessary to specify the column name.
Best regards

SqlDataReader Execution error

i m trying to retrieve the Specialization ID from a table called Specializationtbl, using C# MSVS 2008 and the table includes SpecializationName and SpecializationID beside some other rows and my question is related to some error " No Data to present ", the command goes as bellow:
SqlCommand READSpecID = new SqlCommand("SELECT * FROM Specializationtbl WHERE SpecializationName='" + comboBox1.Text + "'" , DBcnction);
DBcnction.Open();
SqlDataReader ReadSpecID_ = READSpecID.ExecuteReader();
ReadSpecID_.Read();
int SpecID_ = Convert.ToInt16(ReadSpecID_["SpecID"].ToString());
DBcnction.Close();
i also tried to Select the "SpecID" instead of all the rows, but cant seem to seal the query correctly and keep receiving "No data present " error, any idea where am i making the mistake?
1) Try opening DBcnction before assigning the value to READSPecID
DBcnction.Open();
SqlCommand READSpecID = new SqlCommand("SELECT * FROM Specializationtbl WHERE SpecializationName='" + comboBox1.Text + "'" , DBcnction);
2) Run the command in SSMS:
SELECT * FROM Specializationtbl WHERE SpecializationName ='yourvalue'
and see if any results are returned
3) Check comboBox1.Text has a value in it
4) Validate the contents of comboBox1.Text (Or use paremetrised queries or a stored procedure) to ensure you do not become a victim of SQL Injection: http://en.wikipedia.org/wiki/SQL_injection
Refactor to solve your TWO problems:
Your SQL injection problem when building your SQL statement.
Use ExecuteScalar if you only need one value.
Implement using blocks.
string retVal;
using (var conn = new SqlConnection(SomeConnectionString))
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "SELECT SpecID FROM Specializationtbl WHERE SpecializationName= #Name";
cmd.Parameters.AddWithValue("#Name", comboBox1.Text);
conn.Open();
retVal = cmd.ExecuteScalar().ToString();
}
int specID = int.Parse(retVal);
If you really needed more than one value from your statement:
using (var conn = new SqlConnection(SomeConnectionString))
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = "SELECT SpecID, Value2 FROM Specializationtbl WHERE SpecializationName= #Name";
cmd.Parameters.AddWithValue("#Name", comboBox1.Text);
conn.Open();
var dr = cmd.ExecuteReader();
while (dr.Read())
{
Customer c = new Customer {
ID = dr["SpecID"].ToString(),
Value = dr["Value2"].ToString(),
};
}
}
Need to first test if there are any rows. I suspect the query is returning zero rows.
if (ReadSpecID_.HasRows)
{
ReadSpecID_.Read();
}

SQL query from C#

I am trying to query SQL Server database from C#
I have class
Class_A
{
public fetch((string name, string last_name))
{
SqlConnection conn = null;
double val = 0;
string server = "123.444.22.sss";
string dbase = "xyz";
string userid = "cnsk";
string password = "xxxxxx";
string connection = "Data Source=" + server + ";Initial Catalog=" + dbase
+ ";User ID=" + userid + ";Password=" + password;
conn = new SqlConnection(connection);
try
{
conn.Open();
}
catch(Exception)
{
string e = "Database error contact administrator";
MessageBox.Show(e, "Error!");
}
try
{
SqlDataReader myReader = null;
SqlCommand myCommand = new SqlCommand("select * from table where NAME"
+ " = name and LAST_NAME = last_name", conn);
myReader = myCommand.ExecuteReader();
while (myReader.Read())
{
//do something
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
return (0);
}
}
There is a problem in my query.
When I give normal query "select * from table" --- this gives me perfect results.
But when I try to give where condition it gives me error. Any suggestions, to fix this?
Thanks.
Use a parameterised query, and more usings, and stop with the generic exceptions.
something like this where somName and SomeLastName are the values that you wan t to query for.
String sql = "Select * From SomeTable Where [Name] = #Name and [Last_Name] = #LastName";
try
{
using(SqlConnection conn = new SqlConnection(connection))
{
conn.Open();
using( SqlCommand command = new SqlCommand(sql,conn))
{
command.Parameters.Add(new SqlParameter("Name", DbType.String,someName));
command.Parameters.Add(new SqlParameter("LastName", DbType.String,someLastName));
using(IDataReader myReader = command.ExecuteReader())
{
while (myReader.Read())
{
//do something
}
}
}
}
return 0; // Huh?
}
catch(SqlException sex)
{
Console.Writeline(String.Format("Error - {0}\r\n{1}",sex.Message, sex.StackTace))
}
NB not checked might be a silly in it
⚠️ WARNING This answer contains a SQL injection security vulnerability. Do not use it. Consider using a parameterized query instead, as described in some of the other answers to this question (e.g. Tony Hopkinson's answer).
Try adding quotes around the values in the where clause like this:
select * from table where NAME = 'name' and LAST_NAME = 'last_name'
In your case where you are using variables you need to add the quotes and then concatenate the values of the variables into the string. Or you could use String.Format like this:
var sql = String.Format("select * from table where [NAME] = '{0}' and LAST_NAME = '{1}'", name, last_name);
SqlCommand myCommand = new SqlCommand(sql);
Try
select * from table where NAME = 'name' and LAST_NAME = 'last_name'
instead of
select * from table where NAME = name and LAST_NAME = last_name
Edit:
If name and last_name are your parameters then try this:
SqlCommand myCommand = new SqlCommand("select * from table where NAME = #name and LAST_NAME = #last_name", conn);
myCommand.Parameters.AddWithValue( "#name", name );
myCommand.Parameters.AddWithValue( "#last_name", last_name );
Using parameterized commands means that you are invulnerable to a potential huge security hole - sql injection which is possible when command text is manually concatenated.
The text needs to be quoted as others have said--but that's not really the right answer here. Even without malice you're going to run into trouble with the Irish here, look what happens when you try to look for Mr. O'Neill. Use parameters instead.

Categories

Resources