I have the following code in C#-
private void sendnotificationmail(string enqid)
{
try
{
connection.Open();
List<string> maillist = new List<string>();
string sql = "SELECT TrussLog.repmail, TrussLog.branchemail, TrussEnquiry.DesignerEmail FROM TrussLog FULL OUTER JOIN TrussEnquiry ON TrussLog.enquirynum = TrussEnquiry.Enquiry_ID where TrussEnquiry.Enquiry_ID = '" + enqid + "'";
SqlCommand cmd = new SqlCommand(sql);
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
if (!string.IsNullOrEmpty(reader[0].ToString()))
{
maillist.Add(reader[0].ToString());
}
if (!string.IsNullOrEmpty(reader[1].ToString()))
{
maillist.Add(reader[1].ToString());
}
if (!string.IsNullOrEmpty(reader[2].ToString()))
{
maillist.Add(reader[2].ToString());
}
}
connection.Close();
if (result != DialogResult.Cancel)
{
processmail(maillist);
}
}
catch (Exception)
{
}
}
I am getting the value of the variable enqid from a combobox on my Windows form.The contents of the combobox are retrieved from the database. On form load, the combobox displays the first enquiryID retrieved from the database. When I run my program the data reader skips the loop. However if I select a different enquiry in the combobox, the data reader works properly
It seems that you've forgot to associate Command with the Connection:
// SendNotificationMail is more readable then sendnotificationmail
private void sendnotificationmail(string enqid) {
// put IDisposable into using...
using (SqlConnection con = new SqlConnection("ConnectionStringHere")) {
con.Open();
using (SqlCommand cmd = new SqlCommand()) {
cmd.Connection = con; // <- You've omitted this
// have SQL readable
cmd.CommandText =
#"SELECT TrussLog.repmail,
TrussLog.branchemail,
TrussEnquiry.DesignerEmail
FROM TrussLog FULL OUTER JOIN
TrussEnquiry ON TrussLog.enquirynum = TrussEnquiry.Enquiry_ID
WHERE TrussEnquiry.Enquiry_ID = #prm_Id";
// use parametrized queries
cmd.Parameters.AddWithValue("#prm_Id", enqid);
using (SqlDataReader reader = cmd.ExecuteReader()) {
while (reader.Read()) {
...
}
}
}
}
}
And never, never after write code alike
catch (Exception)
{
}
which means "just ignore all the errors and continue".
Related
I'm getting this error on phpMyAdmin
mysqli_connect(): (08004/1040): Too many connections
The only script that is using this DB:
public static bool checkIp(string ip)
{
Console.WriteLine("CHECKIP");
try
{
string sql = " SELECT * FROM `Ip tables` ";
MySqlConnection con = new MySqlConnection("host=hostname;user=username;password=password;database=database;");
MySqlCommand cmd = new MySqlCommand(sql, con);
con.Open();
MySqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
if (ip == reader.GetString("Ip"))
{
Console.WriteLine("Benvenuto, " + reader.GetString("Name"));
con.Close();
return true;
}
}
con.Close();
return false;
}
catch(SqlException exp)
{
throw new InvalidOperationException("Error", exp);
}
}
Does this code close the connection correctly or something is wrong?
EDIT:
I added this block after the catch block
finally
{
if(con.State == System.Data.ConnectionState.Open)
{
con.Close();
}
}
Any better way to write the code? Would finaly block still run if return is executed?
You should put your query in a using statement like this:
string conString= "host=hostname;user=username;password=password;database=database;"
using (MySqlConnection con = new MySqlConnection(conString))
{
con.Open();
using (MySqlCommand com = con.CreateCommand())
{
com.CommandText = "SELECT * FROM `Ip tables`";
using (MySqlDataReader dr = com.ExecuteReader())
{
while (reader.Read())
{
if (ip == reader.GetString("Ip"))
{
Console.WriteLine("Benvenuto, " + reader.GetString("Name"));
con.Close();
return true;
}
}
}
}
}
This will automatically close the connection without having to state con.Close()
I have a code that I use to login.
I call the data I get from textbox with a method and check the records with select query in the
database.
I call to relevant method , when I press the button.
private void btnGiris_Click(object sender, EventArgs e)
{
LoginBilgiler lb = new LoginBilgiler();
bool sonuc = lb.GirisKontrol(txtAd.Text, txtSifre.Text);
}
But I encounter errors in cmd.ExecuteReader the below.
public bool GirisKontrol(string ad,string sifre)
{
using (OracleConnection con = new OracleConnection(connectionString))
{
string query = String.Format("SELECT count(*) from Z_LABEL_USER where USERNAME=({0}) and PASSWORD=({1})", ad,sifre);
OracleCommand cmd = new OracleCommand(query, con);
con.Open();
OracleDataReader dr = cmd.ExecuteReader();
if (dr.HasRows)
{
kAdi = ad;
con.Close();
return true;
}
else
con.Close();
return false;
}
}
The table I use for the select query.
Oracle.ManagedDataAccess.Client.OracleException: 'ORA-01722: invalid
number'
Please, don't hardcode parameters in SQL; parametrize it instead:
public bool GirisKontrol(string ad, string sifre) {
//DONE: validate public methods' input
if (string.IsNullOrEmpty(ad))
return false; // or throw exception
else if (string.IsNullOrEmpty(sifre))
return false; // or throw exception
using (OracleConnection con = new OracleConnection(connectionString)) {
con.Open();
//DONE: no need to count all the entires, just check if there's at least one
//DONE: keep query readable
//DONE: paramterize queries
string query =
#"select 1
from Z_LABEL_USER
where USERNAME = :prm_UserName
and PASSWORD = :prm_Password";
using (OracleCommand cmd = new OracleCommand(query, con)) {
//TODO: this syntax can vary from library to library you use to work with Oracle
cmd.Parameters.Add(":prm_UserName", OracleType.VarChar).Value = ad;
cmd.Parameters.Add(":prm_Password", OracleType.VarChar).Value = sifre;
using (OracleDataReader dr = cmd.ExecuteReader()) {
if (dr.Read()) {
//TODO: Side effect : it changes instance's state. Do you really want it?
kAdi = ad;
return true;
}
}
}
}
return false;
}
So this method is supposed to get the ipaddress of the logged in user from a MySQL Database and print it to a textbox. However, I cant seem to get it right as the program just closes after I execute this method.
public void readIPAddress()
{
string username = GlobalData._sharedUserName;
String connString = System.Configuration.ConfigurationManager.ConnectionStrings["WebAppConnString"].ToString();
conn = new MySql.Data.MySqlClient.MySqlConnection(connString);
conn.Open();
queryStr = "";
queryStr = "SELECT ipaddress FROM webappdemo.userregistration WHERE username=?username";
cmd = new MySql.Data.MySqlClient.MySqlCommand(queryStr, conn);
cmd.Parameters.AddWithValue("?username", username);
cmd.ExecuteReader();
while (cmd.ExecuteReader().Read())
{
textBoxIPAddress.Text = reader["ipaddress"].ToString();
}
conn.Close();
}
If anyone could point out where I went wrong, I greatly appreciate your help!
Edit: After using try and catch I get this:
MySql.Data.MySqlClient.MySqlException (0x80004005): There is already an open DataReader associated with this Connection which must be closed first.
at MySql.Data.MySqlClient.ExceptionInterceptor.Throw(Exception exception)
at MySql.Data.MySqlClient.MySqlConnection.Throw(Exception ex)
at MySql.Data.MySqlClient.MySqlCommand.CheckState()
at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader()
at ConnectToDataBase.Form2.readIPAddress() in C:\Users\ee\Dropbox\ConnectToDataBase\ConnectToDataBase\Form2.cs:line 95
Quick Fix:
You are executing the command two times, using ExecuteReader that's why you are getting such exception. If you execute the code like this means your code will works fine:
string queryStr = "SELECT ipaddress FROM webappdemo.userregistration WHERE username=#username";
using (MySqlConnection conn = new MySqlConnection(connString))
{
conn.Open();
using (MySqlCommand cmd = new MySqlCommand(queryStr, conn))
{
cmd.Parameters.AddWithValue("#username", username);
var reader = cmd.ExecuteReader();
while (reader.Read())
{
textBoxIPAddress.Text = reader["ipaddress"].ToString();
}
}
}
Smart Fix:
Here you are fetching a single value from the database in such situations you need not to use reader at all. you can simply access those value by using ExecuteScalar() method, which will give you the required object. if so You can use the following code:
using(MySqlConnection conn = new MySqlConnection(connString))
{
using(MySqlCommand cmd= new MySqlCommand(query, conn))
{
cmd.Parameters.Add("#username", username);
conn.Open();
object ipAddress= cmd.ExecuteScalar();
if (ipAddress!= null)
textBoxIPAddress.Text = ipAddress.ToString();
else
textBoxIPAddress.Text = "No data found";
}
}
Hope that you wont forget to add MySql.Data.MySqlClient; to the using section
you are executing reader two times by calling ExecuteReader(), why you need Reader here, if you only need one value from database. use ExecuteScalar that will return first value of the first record from the result. Sample code:
try
{
string query = "SELECT ipaddress FROM webappdemo.userregistration WHERE username = #username";
string connString =ConfigurationManager.ConnectionStrings["WebAppConnString"].ToString();
using(MySqlConnection connection = new MySqlConnection(connString))
{
using(MySqlCommand command = new MySqlCommand(query, connection))
{
command.Parameters.Add("#username", username);
connection.Open();
object ip= command.ExecuteScalar();
if (ip != null) {
textBoxIPAddress.Text = ip.ToString();
}
}
}
}
catch(MySqlException ex)
{
// do something with the exception
}
Problem:
cmd.ExecuteReader(); //Executing reader and not assigning to anything
while (cmd.ExecuteReader().Read()) //Executing reader again and not assigning to anything again
{
//There is nothing assigned to reader.
textBoxIPAddress.Text = reader["ipaddress"].ToString();
}
Quick Solution:
//assuming reader is defined
reader = cmd.ExecuteReader();
while (reader.Read()) //read from the reader
{
textBoxIPAddress.Text = reader["ipaddress"].ToString();
}
Alternative Solutions using MySql.Data.MySqlClient.MySqlHelper:
try {
object ip = MySqlHelper.ExecuteScalar(connString, query, new MySqlParameter[] {
new MySqlParameter("?username", username)
}));
if (ip != null) {
textBoxIPAddress.Text = ip.ToString();
}
} catch (Exception ex) {
// do something with the exceptio
}
If you insist on using reader:
//assuming reader is defined
reader = MySqlHelper.ExecuteReader(connString, query, new MySqlParameter[] {
new MySqlParameter("?username", username)
}));
while (reader.Read()) //read from the reader
{
textBoxIPAddress.Text = reader["ipaddress"].ToString();
}
Note: the above code is just typed in here and may contain syntax errors. take this a a guideline.
I am creating a sql project. I used a SqlDatareader and textbox, but when I run it I got an error
InvalidOperationException
My code is this, thanks for your help.
protected void DropDownList2_SelectedIndexChanged(object sender, EventArgs e)
{
if (DropDownList1.SelectedIndex == 0)
{
string CS = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
using (SqlConnection con = new SqlConnection(CS))
{
con.Open();
SqlCommand cmd = new SqlCommand
("USE [PRODUCTS] SELECT QUALITIES FROM dbo.COMPUTERS WHERE ID = 0", con);
SqlDataReader reader;
reader = cmd.ExecuteReader();
TextBox1.Text = reader["QUALITIES"].ToString();
}
}
}
You are not accounting for the case where your data reader has no rows.
Try this:
while(reader.Read())
{
TextBox1.Text = reader["QUALITIES"].ToString();
}
Also note that the "Qualities" field in your database could potentially be null. You will want to protect against this as well.
You should do a couple of error-checking tasks to better understand what is causing the problem. Use a try/catch to analyze the exception more closely. Also add a Finally block to close the reader. And check if the reader has rows:
reader = cmd.ExecuteReader();
try
{
if (reader.HasRows)
{
reader.Read();
if (!reader.IsDBNull(0))
TextBox1.Text = reader.GetString(0);
}
}
catch (Exception ex)
{
// Do something
}
finally
{
reader.Close();
}
I am trying to use a SqlDataReader to run a query and then display the results in a messagebox, but I keep getting the error
Invalid attempt to read when no data is present.
Here is my code.
public void button1_Click(object sender, EventArgs e)
{
string results = "";
using (SqlConnection cs = new SqlConnection(#"Server=100-nurex-x-001.acds.net;Database=Report;User Id=reports;Password=mypassword"))
{
cs.Open();
string query = "select stationipaddress from station where stationname = #name";
using (SqlCommand cmd = new SqlCommand(query, cs))
{
// Add the parameter and set its value --
cmd.Parameters.AddWithValue("#name", textBox1.Text);
using (SqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
label3.Text = dr.GetSqlValue(0).ToString();
results = dr.GetValue(0).ToString();
//MessageBox.Show(dr.GetValue(0).ToString());
//MessageBox.Show(results);
}
MessageBox.Show(results);
}
}
}
}
That's correct.
When you exit from the while loop the DataReader has reached the end of the loaded data and thus cannot be used to get the value of a non-existant current record.
The Read method advances the SqlDataReader (dr) to the next record and it returns true if there are more rows, otherwise false.
If you have only one record you could use the results variable in this way
MessageBox.Show(results);
Now, this will work because you have a TOP 1 in your sql statement, but, if you have more than one record, it will show only the value of the last record.
Also as noted by marc_s in its comment, if your table is empty, your code doesn't fall inside the while loop, so probably you could initialize the results variable with a message like:
results = "No data found";
EDIT: Seeing your comment below then you should change your code in this way
.....
// Use parameters **ALWAYS** -- **NEVER** cancatenate/substitute strings
string query = "select stationipaddress from station where stationname = #name";
using (SqlCommand cmd = new SqlCommand(query, cs))
{
// Add the parameter and set its value --
cmd.Parameters.AddWithValue("#name", textBox1.Text);
using (SqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
label3.Text = dr.GetSqlValue(0).ToString();
results = dr.GetValue(0).ToString();
}
}
}
.....
I ran into a similar issue trying to get a GUID I knew was there - I could run the same SQL directly in SQL Management Studio and get my result. So instead of trying to bring it back as a GUID (it was saved in a char(35) field, even though it really was a GUID!), I brought it back as a string, instead:
SqlConnection sqlConn = null;
string projId = String.Empty;
string queryString = "SELECT * FROM project WHERE project_name='My Project'";
try
{
sqlConn = new SqlConnection(connString);
SqlCommand cmd = new SqlCommand(queryString, sqlConn);
sqlConn.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
projId = reader.GetSqlValue(0).ToString(); // <-- safest way I found to get the first column's parameter -- increment the index if it is another column in your result
}
}
reader.Close();
sqlConn.Close();
return projId;
}
catch (SqlException ex)
{
// handle error
return projId;
}
catch (Exception ex)
{
// handle error
return projId;
}
finally
{
sqlConn.Close();
}