Trying to learn C# and I can't quite get a handle on querying and getting results. I'm trying to figure out both how to and the best way of doing the below in C# .NET. It's a MySql database.
//Interact with the DB. Find out if this hashed account #'s in there.
$dbh = $this->getPDO();
$procedure = "SELECT userPass FROM 499Users WHERE accName = :acc";
$call = $dbh->prepare($procedure);
$call->bindParam(':acc', $testAcc, PDO::PARAM_STR);
$call->execute();
//Fetch up to 1 result row
$row = $call->fetch(PDO::FETCH_ASSOC);
This is my latest try: Also I realize I should probably be using parameters, but I just want it to work first
MySqlConnectionStringBuilder conn_string = new MySqlConnectionStringBuilder();
conn_string.Server = "*";
conn_string.UserID = "*";
conn_string.Password = "*";
conn_string.Database = "*";
conn_string.Port = 3306;
MySqlConnection connection = new MySqlConnection(conn_string.ToString());
try
{
Console.WriteLine("Trying to connect to: ..." + conn_string); Console.WriteLine("Connecting to MySQL...");
connection.Open();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
string hashedAcc = this.HashPassword(acc);
//Verify hashed account
string query = "SELECT userPass FROM 49Users WHERE accName =" + hashedAcc;
MySqlCommand cmd = new MySqlCommand(query, connection);
MySqlDataReader myReader;
myReader = cmd.ExecuteReader();
try
{
while (myReader.Read())
{
Console.WriteLine(myReader.GetString(0));
}
}
finally
{
myReader.Close();
connection.Close();
}
The following WHERE clause:
WHERE accName =" + hashedAcc;
will cause an error if accName is not of type int, it needs quotes around it.
You should use parameterized query just like you did in PDO, it avoid errors like this and SQL injections as well.
var query = "SELECT userPass FROM 49Users WHERE accName = #hashedAcc";
var cmd = new MySqlCommand(query, connection);
cmd.Parameters.AddWithValue("#hashedAcc", hashedAcc);
Related
In Excel writing a VSTO Plugin (using C#) I'm trying to retrieve a value from a SQL database using OLEDB. When I debug this function, it fails on the catch.
The message I get is:
must declare the scalar variable \"#uname\"
But I already did this when I bound the parameter. What am I doing wrong?
public static int getUserID(string username)
{
int result = 0;
string sql = #"select top 1 [ID] FROM " + tbl_users + " WHERE ( [UNAME]=#uname );";
Console.WriteLine("sql: " + sql);
using (OleDbConnection conn = new OleDbConnection(connStr))
{
try
{
conn.Open();
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = conn;
cmd.CommandText = sql;
cmd.Parameters.AddWithValue("#uname", username);
result = (int)cmd.ExecuteScalar();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
result = -15;
}
finally
{
conn.Close();
conn.Dispose();
}
}
return result;
}
So I think I figured it out... This change works, but I don't really like it.
First I need to use OleDb parameter binding and not SqlParameter binding.
It also seems like OleDb does not like custom naming parameters like #uname and instead relies on the order of parameters (I don't like this).
So here's the fix in case anyone was interested:
public static int getUserID(string username)
{
int result = 0;
string sql = #"select top 1 [ID] FROM " + tbl_users + " WHERE ( [UNAME]=? );";
Console.WriteLine("sql: " + sql);
using (OleDbConnection conn = new OleDbConnection(connStr))
{
try
{
conn.Open();
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = conn;
cmd.CommandText = sql;
cmd.Parameters.Add("?", OleDbType.VarChar).Value = Convert.ToString(username);
result = (int)cmd.ExecuteScalar();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
result = -15;
}
finally
{
conn.Close();
conn.Dispose();
}
}
return result;
}
I'm trying to populate two ArrayLists (listOfAnswers and listOfAnswerIDs) with fields from a database ('answer' and 'answer_id').
The following code seems to work perfectly fine when question_id=1 in the string cmdText. However, if I change this to 2 or 3, the ArrayLists remain empty and I don't know why. Any ideas?
I think it's to do with the string cmdGetAnswersQuery as "SELECT * FROM answers WHERE question_id=2" works...
string connStr = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
MySqlConnection conn = new MySqlConnection(connStr);
MySqlDataReader reader;
ArrayList listOfAnswerIDs = new ArrayList();
ArrayList listOfAnswers = new ArrayList();
try
{
conn.Open();
string cmdText = "SELECT * FROM questions_t WHERE question_id=2";
MySqlCommand cmd = new MySqlCommand(cmdText, conn);
cmd.Parameters.Add("#ModuleID", MySqlDbType.Int32);
cmd.Parameters["#ModuleID"].Value = ddlModules.SelectedValue;
reader = cmd.ExecuteReader();
if (reader.Read())
{
lblQuestion.Text = reader["question"].ToString();
ViewState["QuestionID"] = reader["question_id"].ToString();
ViewState["AnswerID"] = reader["correct_answer_id"].ToString();
reader.Close();
string cmdGetAnswersQuery = "SELECT * FROM answers WHERE question_id=#QuestionID";
MySqlCommand cmdGetAnswers = new MySqlCommand(cmdGetAnswersQuery, conn);
cmdGetAnswers.Parameters.Add("#QuestionID", MySqlDbType.Int32);
cmdGetAnswers.Parameters["#QuestionID"].Value = ViewState["AnswerID"];
reader = cmdGetAnswers.ExecuteReader();
while (reader.Read())
{
listOfAnswerIDs.Add(reader["answer_id"].ToString());
listOfAnswers.Add(reader["answer"].ToString());
}
reader.Close();
populateAnswers(listOfAnswers, listOfAnswerIDs);
}
else
{
reader.Close();
lblError.Text = "(no questions found)";
}
}
catch
{
lblError.Text = "Database connection error - failed to insert record.";
}
finally
{
conn.Close();
}
The actual database contents are shown here:
http://i.imgur.com/3S4lV60.png
http://i.imgur.com/8A913xF.png
I can't say for sure that this is the problem, but the first thing I'd look at is this line of code:
cmdGetAnswers.Parameters["#QuestionID"].Value = ViewState["AnswerID"];
I suspect you want that to be ViewState["QuestionID"].
I want to perform 2 queries in one button click. I tried the
string query = "first query";
query+="second query";
But this didn't work it shows error.
I have now created 2 separate connections like below:
try
{
SqlConnection conn1 = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionStringDatabase"].ConnectionString);
//open connection with database
conn1.Open();
//query to select all users with teh given username
SqlCommand com1 = new SqlCommand("insert into artikulli (tema,abstrakti, kategoria_id, keywords ) values (#tema, #abstrakti, #kategoria, #keywords)", conn1);
// comand.Parameters.AddWithValue("#id", iD);
com1.Parameters.AddWithValue("#tema", InputTitle.Value);
com1.Parameters.AddWithValue("#abstrakti", TextareaAbstract.Value);
com1.Parameters.AddWithValue("#kategoria", DropdownCategory.Value);
com1.Parameters.AddWithValue("#keywords", InputTags.Value);
//execute queries
com1.ExecuteNonQuery();
conn1.Close();
if (FileUploadArtikull.HasFile)
{
int filesize = FileUploadArtikull.PostedFile.ContentLength;
if (filesize > 4194304)
{
ScriptManager.RegisterStartupScript(this, this.GetType(), "popup", "alert('Maximumi i madhesise eshte 4MB');", true);
}
else
{
string filename = "artikuj/" + Path.GetFileName(FileUploadArtikull.PostedFile.FileName);
SqlConnection conn2 = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionStringDatabase"].ConnectionString);
SqlCommand com2 = new SqlCommand("insert into artikulli(path) values ('" + filename + "')", conn2);
//open connection with database
conn2.Open();
com2.ExecuteNonQuery();
FileUploadArtikull.SaveAs(Server.MapPath("~/artikuj\\" + FileUploadArtikull.FileName));
Response.Redirect("dashboard.aspx");
}
}
else
{
ScriptManager.RegisterStartupScript(this, this.GetType(), "popup", "alert('Ju nuk keni perzgjedhur asnje file');", true);
}
}
But the problem is that only the second query is performed and the firs is saved as null in database
In your case, there is no reason to open two connections. In addition, the C# language has evolved, so I recommend using the power given by the new language constructs (using, var).
Here is an improved version that should work assuming that the values you bind to your parameters are valid:
try
{
using(var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionStringDatabase"].ConnectionString))
{
//open connection with database
connection.Open();
//query to select all users with teh given username
using(var command1 = new SqlCommand("insert into artikulli (tema,abstrakti, kategoria_id, keywords ) values (#tema, #abstrakti, #kategoria, #keywords)", connection))
{
command1.Parameters.AddWithValue("#tema", InputTitle.Value);
command1.Parameters.AddWithValue("#abstrakti", TextareaAbstract.Value);
command1.Parameters.AddWithValue("#kategoria", DropdownCategory.Value);
command1.Parameters.AddWithValue("#keywords", InputTags.Value);
//execute first query
command1.ExecuteNonQuery();
}
//build second query
string filename = "artikuj/" + Path.GetFileName(FileUploadArtikull.PostedFile.FileName);
using(SqlCommand command2 = new SqlCommand("insert into artikulli(path) values (#filename)", connection))
{
//add parameters
command2.Parameters.AddWithValue("#filename", filename);
//execute second query
command2.ExecuteNonQuery();
}
}
}
//TODO: add some exception handling
//simply wrapping code in a try block has no effect without a catch/finally
Try below code, No need to open the connection twice
string query1 = "insert into artikulli (tema,abstrakti, kategoria_id, keywords ) values (#tema, #abstrakti, #kategoria, #keywords)";
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionStringDatabase"].ConnectionString);
SqlCommand com1= new SqlCommand(query1, conn);
com1.Parameters.AddWithValue("#tema", InputTitle.Value);
com1.Parameters.AddWithValue("#abstrakti", TextareaAbstract.Value);
com1.Parameters.AddWithValue("#kategoria", DropdownCategory.Value);
com1.Parameters.AddWithValue("#keywords", InputTags.Value);
string query2 = "insert into artikulli(path) values ('" + filename + "')", conn);
comm.ExecuteNonQuery();
comm.CommandText = query2;
comm.ExecuteScalar();
I'm trying to make a login facility for Windows Forms Application project. I'm using Visual Studio 2010 and MS Sql Server 2008.
I referenced this article:
http://www.codeproject.com/Articles/4416/Beginners-guide-to-accessing-SQL-Server-through-C
Here is my database table named user:
I have TextBox1 for user name , TextBox2 for user password and Button1 for starting login process. Here is my code for Button1_Click method:
private void button1_Click(object sender, EventArgs e)
{
string kullaniciAdi; // user name
string sifre; // password
SqlConnection myConn = new SqlConnection();
myConn.ConnectionString = "Data Source=localhost; database=EKS; uid=sa; pwd=123; connection lifetime=20; connection timeout=25; packet size=1024;";
myConn.Open();
try
{
SqlDataReader myReader;
string myQuery = ("select u_password from user where u_name='" + textBox1.Text + "';");
SqlCommand myCommand = new SqlCommand(myQuery,myConn);
myReader = myCommand.ExecuteReader();
while (myReader.Read())
{
sifre = myReader["u_password"].ToString();
}
}
catch (Exception x)
{
MessageBox.Show(x.ToString());
}
myConn.Close();
}
I don't have much experience with C# but i think i'm missing something small to do it right. Below i share exception message that i catched. Can you show me what i'm missing? (line 33 is myReader = myCommand.ExecuteReader();)
Considerin given answers, i updated my try block as in below but it still does not work.
try
{
SqlDataReader myReader;
string myQuery = ("select u_password from [user] where u_name=#user");
SqlCommand myCommand = new SqlCommand(myQuery, myConn);
myCommand.Parameters.AddWithValue("#user", textBox1.Text);
myReader = myCommand.ExecuteReader();
while (myReader.Read())
{
sifre = myReader["u_password"].ToString();
}
if (textBox2.Text.Equals(sifre))
{
Form2 admnPnl = new Form2();
admnPnl.Show();
}
}
After changing whole code as below by sine's suggestion, screenshot is also below:
And i think, somehow i cannot assign password in database to the string sifre.
code:
string sifre = "";
var builder = new SqlConnectionStringBuilder();
builder.DataSource = "localhost";
builder.InitialCatalog = "EKS";
builder.UserID = "sa";
builder.Password = "123";
using (var conn = new SqlConnection(builder.ToString()))
{
using (var cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.CommandText = "select u_password from [user] where u_name = #u_name";
cmd.Parameters.AddWithValue("#u_name", textBox1.Text);
conn.Open();
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var tmp = reader["u_password"];
if (tmp != DBNull.Value)
{
sifre = reader["u_password"].ToString();
}
}
if (textBox2.Text.Equals(sifre))
{
try
{
AdminPanel admnPnl = new AdminPanel();
admnPnl.Show();
}
catch (Exception y)
{
MessageBox.Show(y.ToString());
}
}
else
{
MessageBox.Show("incorrect password!");
}
}
}
}
User is a reserved keyword in T-SQL. You should use it with square brackets like [User].
And you should use parameterized sql instead. This kind of string concatenations are open for SQL Injection attacks.
string myQuery = "select u_password from [user] where u_name=#user";
SqlCommand myCommand = new SqlCommand(myQuery,myConn);
myCommand.Parameters.AddWithValue("#user", textBox1.Text);
As a general recomendation, don't use reserved keywords for your identifiers and object names in your database.
Try to put user into [ ] because it is a reseved Keyword in T-SQL and use Parameters, your code is open to SQL-Injection!
private void button1_Click(object sender, EventArgs e)
{
var builder = new SqlConnectionStringBuilder();
builder.DataSource = "servername";
builder.InitialCatalog = "databasename";
builder.UserID = "username";
builder.Password = "yourpassword";
using(var conn = new SqlConnection(builder.ToString()))
{
using(var cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.CommandText = "select u_password from [user] where u_name = #u_name";
cmd.Parameters.AddWithValue("#u_name", textBox1.Text);
conn.Open();
using(var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var tmp = reader["u_password"];
if(tmp != DBNull.Value)
{
sifre = reader["u_password"].ToString();
}
}
}
}
}
}
USER is a reserved word in T-SQL
Try putting [] around reserved words.
string myQuery = ("select u_password from [user] where u_name='" + textBox1.Text + "';");
user is a keyword.
Change it to something like
string myQuery = ("select u_password from [user] where u_name='" + textBox1.Text + "';");
Futher to that I recomend you have a look at Using Parameterized queries to prevent SQL Injection Attacks in SQL Server
User is a reserved keyword in SQL, you need to do this:
select u_password from [user] where u_name=#user
And as ever, with basic SQL questions, you should always use parameterised queries to prevent people from running any old commands on your DB via a textbox.
SqlCommand myCommand = new SqlCommand(myQuery,myConn);
myCommand.Parameters.AddWithValue("#user", textBox1.Text);
I have error in this code. What should happen is if I have two stall in the database, the stall price must be doubled, but what happened in this code is if I have two stall in the database, the stall price isn't doubled and if I only have one stall the stall price is 0.
public double GetStallPrice(int commtaxno)
{
try
{
string query = "SELECT * FROM contract_details WHERE comm_tax_no = " + commtaxno;
DatabaseString myConnectionString = new DatabaseString();
OleDbConnection connection = new OleDbConnection();
connection.ConnectionString = myConnectionString.connect();
connection.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
command.CommandText = query;
OleDbDataReader stallReader = command.ExecuteReader();
stallReader.Read();
while(stallReader.Read())
{
try
{
string query2 = "SELECT section_ID FROM specific_stall WHERE stall_no = '" + stallReader["stall_no"].ToString() + "'";
OleDbCommand command2 = new OleDbCommand();
command2.Connection = connection;
command2.CommandText = query2;
OleDbDataReader sectionReader = command2.ExecuteReader();
sectionReader.Read();
sectionid = Convert.ToInt32(sectionReader["section_ID"].ToString());
try
{
string query3 = "SELECT stall_price FROM stall_sections WHERE section_ID = " + sectionid;
OleDbCommand command3 = new OleDbCommand();
command3.Connection = connection;
command3.CommandText = query3;
OleDbDataReader stallPriceReader = command3.ExecuteReader();
stallPriceReader.Read();
stall_price = Convert.ToDouble(stallPriceReader["stall_price"].ToString());
}
catch (Exception c)
{
MessageBox.Show(c.GetBaseException().ToString());
}
}
catch (Exception b)
{
MessageBox.Show(b.GetBaseException().ToString());
}
sum_stall_price = sum_stall_price + stall_price;
}
connection.Close();
}
catch (Exception a)
{
MessageBox.Show(a.GetBaseException().ToString());
}
return sum_stall_price;
}
I think the error is here:
stallReader.Read();
while(stallReader.Read())
You read first record and then read the second, without processing the first.
You have to remove first row and leave just
while(stallReader.Read())
As a side note, you should try to always use using syntax with classes that implement IDisposable interface. So, just an example:
using (OleDbConnection connection = new OleDbConnection())
{
// All the code inside
}
In this way you're sure that the object is properly released.
Finally: do not compose queries manually, but use parameters instead!!
Using parameters can avoid SQL injection and many headaches due to numeric (float, double, currency) and dates conversion!!