Hi there its the first time to use stackoverflow so hi every one L)
i'm a beginner into C# forms i take it as a fun hobby.
SqlCommand comm = new SqlCommand("SELECT COUNT(*) FROM Members where sponser = "
+textbox1.text+"'", connection);
Int32 count = (Int32)comm.ExecuteScalar();
textbox2.Text ="Found "+ count+" Members;
well its just a mix between 2 codes i have got from google xD
how ever the error appear here textbox2.Text ="Found "+ count+" Members;
There are a couple of things wrong with this line of code:
textbox2.Text ="Found "+ count+" Members;
First of all, there's a syntax error. You never close the second set of quotes. You'd do so like this:
textbox2.Text ="Found "+ count+" Members";
However, string concatenation like this is still a little messy. You have two literal strings and you're trying to add them to an integer, which isn't entirely intuitive (and probably slower than it needs to be). Instead, consider using a formatting string:
textbox2.Text = string.Format("Found {0} Members", count);
This will take the value from count (which is an integer) and, internally to the string.Format() function, discern its string representation and insert it into the placeholder in the formatted string.
UPDATE: That takes care of the compile-time errors. Now you're going to get a run-time error from this:
SqlCommand comm = new SqlCommand("SELECT COUNT(*) FROM Members where sponser = "
+textbox1.text+"'", connection);
As soon as you try to execute that SQL statement you're going to get an error from the database because the resulting query has a syntax error:
SELECT COUNT(*) FROM Members where sponser = some text'
You're missing the opening single-quote for the parameter. Something like this:
SqlCommand comm = new SqlCommand("SELECT COUNT(*) FROM Members where sponser = '"
+textbox1.text+"'", connection);
However, and this is important, you're still not done. This line of code is wide open to a very common and easily exploitable vulnerability called SQL Injection. You'll want to move away from direct string concatenation and use parameters for your SQL queries. Something like this:
SqlCommand cmd = new SqlCommand("SELECT COUNT(*) FROM Members where sponser = #sponser");
cmd.Parameters.Add("#sponser", textbox1.text);
Int32 count = (Int32)comm.ExecuteScalar();
Know that there is still a lot more you can do to improve this, which is all worth learning over time. Things you can look into are:
Checking and validating user input (textbox1.text) before you even try to use it in a SQL query.
Checking the output of comm.ExecuteScalar() before trying to directly cast it to an Int32 (this would give you a runtime error if it returns anything other than an integer for some reason).
Consider using something like Linq to Sql in place of ADO.NET components as it does a lot more for you with less code on your part.
protected void Page_Load(object sender, EventArgs e)
{
lb1.Text = GetRecordCount(textbox2.Text).ToString();
}
private int GetRecordCount(string myParameter)
{
string connectionString = ConfigurationManager.ConnectionStrings["DBConnection"].ToString();
Int32 count = 0;
string sql = "SELECT COUNT(*) FROM members WHERE sponsor = #Sponsor";
using (SqlConnection conn = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.Add("#Sponsor", SqlDbType.VarChar);
cmd.Parameters["#Sponsor"].Value = myParameter;
try
{
conn.Open();
count = (Int32)cmd.ExecuteScalar();
}
catch (Exception ex)
{
}
}
return (int)count;
}
You are missing a closing " at the end:
textbox2.Text ="Found "+ count+" Members";
You code is vulnerable to SQL Injections. Please consider using Parameters.
private int GetMemberCount(string connectionString, string sponsor)
{
using(var connection = new SqlConnection(connectionString))
using(var command = connection.CreateCommand())
{
command.CommandText = "SELECT COUNT(*) FROM members WHERE sponsor = #Sponsor";
command.Parameters.AddWithValue("#Sponsor", sponsor);
return Convert.ToInt32(command.ExecuteScalar());
}
}
//Usage
var sponsor = textbox1.text;
var count = GetMemberCount(connectionString, sponsor);
textbox2.Text = string.Format("Found {0} Members", count);
Related
I am somwhat new to SQL, so I am not sure I am going about this the right way.
I am trying to fetch data from my SQL Server database where I want to find out if checkedin is 1/0, but it needs to search on a specific user and sort after the newest date as well.
What I am trying to do is something like this:
string connectionString = ".....";
SqlConnection cnn = new SqlConnection(connectionString);
SqlCommand checkForInOrOut = new SqlCommand("SELECT CHECKEDIN from timereg ORDER BY TIME DESC LIMIT 1 WHERE UNILOGIN = '" + publiclasses.unilogin + "'", cnn);
So my question, am I doing this right? And how do I fetch the data collected, if everything was handled correctly it should return 1 or 0. Should I use some sort of SqlDataReader? I am doing this in C#/WPF
Thanks
using (SqlDataReader myReader = checkForInOrOut.ExecuteReader())
{
while (myReader.Read())
{
string value = myReader["COLUMN NAME"].ToString();
}
}
This is how you would read data from SQL, but i recommend you looking into Parameters.AddWithValue
There are some errors in your query. First WHERE goes before ORDER BY and LIMIT is an MySql keyword while you are using the Sql Server classes. So you should use TOP value instead.
int checkedIn = 0;
string cmdText = #"SELECT TOP 1 CHECKEDIN from timereg
WHERE UNILOGIN = #unilogin
ORDER BY TIME DESC";
string connectionString = ".....";
using(SqlConnection cnn = new SqlConnection(connectionString))
using(SqlCommand checkForInOrOut = new SqlCommand(cmdText, cnn))
{
cnn.Open();
checkForInOrOut.Parameters.Add("#unilogin", SqlDbType.NVarChar).Value = publiclasses.unilogin;
// You return just one row and one column,
// so the best method to use is ExecuteScalar
object result = checkForInOrOut.ExecuteScalar();
// ExecuteScalar returns null if there is no match for your where condition
if(result != null)
{
MessageBox.Show("Login OK");
// Now convert the result variable to the exact datatype
// expected for checkedin, here I suppose you want an integer
checkedIN = Convert.ToInt32(result);
.....
}
else
MessageBox.Show("Login Failed");
}
Note how I have replaced your string concatenation with a proper use of parameters to avoid parsing problems and sql injection hacks. Finally every disposable object (connection in particular) should go inside a using block
This question already has answers here:
ExecuteNonQuery: Connection property has not been initialized.
(7 answers)
Closed 7 years ago.
I keep getting this error saying that "ExecuteScalar has not been initialized" I have new to C# but had a look through google and tutorials and still cant see what the problem is. Its probably a very silly mistake but if anyone could help. Thanks :)
// open connection
myConnection.Open();
// sql command
string Account_Num = txt_acc.Text;
string Pin_num = txt_pin.Text;
SqlCommand check_details = new SqlCommand("select Account_num, Pin_num from Cust_details where Account_num='" + txt_acc.Text + "'and Pin_num ='" + txt_pin.Text + "'");
check_details.Parameters.AddWithValue("#Account_num", txt_acc.Text);
check_details.Parameters.AddWithValue("#Pin_num", txt_pin.Text);
int result = Convert.ToInt32(check_details.ExecuteScalar());
if (result > 0)
{
Console.WriteLine("user exists");
}
else
{
Console.WriteLine("error");
}
}
Looks like you didn't connect your command with connection. Just set it's Connection property to myConnection.
check_details.Connection = myConnection;
or you can set it on your SqlCommand constructor as a second parameter;
SqlCommand check_details = new SqlCommand("yourCommand", myConnection);
or you can use CreateCommand method from your connection;
SqlCommand check_details = myConnection.CreateCommand();
And you are misunderstood the parameterized queries. You still do string concatenation in your sql query but you try to add parameters. That's meaningless.
Use using statement to dispose your connection and command automatically as well.
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 and it's size.
using(var myConnection = new SqlConnection(conString))
using(var check_details = myConnection.CreateCommand())
{
check_details.CommandText = #"select Account_num, Pin_num from Cust_details
where Account_num = #accnum
and Pin_num = #pinnum";
// I assume your column types as Int
check_details.Parameters.Add("#accnum", SqlDbType.Int).Value = int.Parse(txt_acc.Tex);
check_details.Parameters.Add("#pinnum", SqlDbType.Int).Value = int.Parse(txt_pin.Text);
myConnection.Open();
int result = (int)check_details.ExecuteScalar();
...
}
By the way, there is no point to select Pin_num column in your command since ExecuteScalar ignores it.
I tried to update a paragraph from mysql table,but i got error like this
"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 's first-ever super-villainess."
My mysql Query
cmd.CommandText = "UPDATE `moviemaster` SET `Runtime`='" + runtime + "',`DateMasterId`='" + dateid + "',`Trailer`='" + trailer + "',`Synopsis`='" + synopsis + "' WHERE `MovieMasterId`='" + movieid + "'";
I got error in 'synopsis',it's a big data containing a large paragraph.If i romove 'Synopsis' section from the query,everything working fine.What exactly the problem.How can i resolve this?
#SonerGönül:Ok,fine.. then please show me an example of parameterised
query
Sure. I also wanna add a few best practice as well.
Use using statement to dispose your connection and command automatically.
You don't need to escape every column with `` characters. You should only escape if they are reserved keywords for your db provider. Of course, at the end, changing them to non-reserved words is better.
Do not use AddWithValue method. It may generate upexpected and surprising result sometimes. Use Add method overload to specify your parameter type and it's size.
using (var con = new SqlConnection(conString))
using(var cmd = con.CreateCommand())
{
cmd.CommandText = #"UPDATE moviemaster
SET Runtime = #runtime, DateMasterId = #dateid, Trailer = #trailer, Synopsis = #synopsis
WHERE MovieMasterId = #movieid";
cmd.Parameters.Add("#runtime", MySqlDbType.VarChar).Value = runtime; ;
cmd.Parameters.Add("#dateid", MySqlDbType.VarChar).Value = dateid;
cmd.Parameters.Add("#trailer", MySqlDbType.VarChar).Value = trailer;
cmd.Parameters.Add("#synopsis", MySqlDbType.VarChar).Value = synopsis;
cmd.Parameters.Add("#movieid", MySqlDbType.VarChar).Value = movieid;
// I assumed your column types are VarChar.
con.Open();
cmd.ExecuteNonQuery();
}
Please avoid using inline query. Your database can be subjected to SQL Injection. See this example, on what can be done using SQL Injection.
And use paramterized query instead. Here is the example taken from here. This way, even if your string has special characters, it will not break and let you insert/update/select based on parameters.
private String readCommand = "SELECT LEVEL FROM USERS WHERE VAL_1 = #param_val_1 AND VAL_2 = #param_val_2;";
public bool read(string id)
{
level = -1;
MySqlCommand m = new MySqlCommand(readCommand);
m.Parameters.AddWithValue("#param_val_1", val1);
m.Parameters.AddWithValue("#param_val_2", val2);
level = Convert.ToInt32(m.ExecuteScalar());
return true;
}
and finally, your query will become
cmd.CommandText = "UPDATE `moviemaster` SET `Runtime`= #param1,`DateMasterId`= #dateid, `Trailer`= #trailer,`Synopsis`= #synopsis WHERE `MovieMasterId`= #movieid";
cmd.Parameters.AddWithValue("#param1", runtime);
cmd.Parameters.AddWithValue("#dateid", dateid);
cmd.Parameters.AddWithValue("#trailer", trailer);
cmd.Parameters.AddWithValue("#synopsis", synopsis);
cmd.Parameters.AddWithValue("#movieid", movieid);
SqlConnection cn = new SqlConnection("user id=ID;" +
"password=PASS;server=svr;" +
"Trusted_Connection=no;" +
"database=db; " +
"connection timeout=30");
cn.Open();
SqlCommand command1 = new SqlCommand();
command1.Connection = cn;
Console.WriteLine(ListofOrders.Count);
for (int i = 0; i < ListofOrders.Count; i++)
command1.CommandText += string.Format("update table set Status='Expired' where GUID={0};", ListofOrders[i].ToString());
command1.ExecuteNonQuery();
// LogicHandler.UpdateActiveOrders();
Console.WriteLine("DONE", ConsoleColor.Cyan);
Getting error at this step: command1.ExecuteNonQuery(); Error Message: The multi-part identifier could not be bound.
What i am trying here is I am running a select query and getting that data into the ListofOrders list from that I wanna run the update to those data in the list.
Please help
If you use a Reserved Keyword like table you have to wrap it in square brackets: [table]. But it would be better to not use them in the first place.
I guess you need to wrap the Guid with apostrophes like in GUID='{0}'. Howver, you should use sql-parameters instead of string concatenation, always. That prevents also sql-injection.
string update = #"update tablename -- or [Table] but i wouldnt do that
set Status='Expired'
where GUID=#GUID";
command1.CommandText = update;
command1.Parameters.Add("#GUID", SqlDbType.UniqueIdentifier).Value = new Guid(ListofOrders[i].ToString());
As an aside, why have you used command1.CommandText += instead of just command1.CommandText =? That is at least confusing, if you reuse the command it could also cause errors.
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+"' ";