I have a problem in SqlDataReader - it cannot proceed into while and cannot while.
Here is my code
List<tmp_WatchList> data = new List<tmp_WatchList>();
using (SqlConnection con = new SqlConnection(conStr))
{
using (SqlCommand cmd = new SqlCommand("sp_CheckPersonList", con))
{
try
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#Name", SqlDbType.NVarChar).Value = name;
SqlDataReader oReader = cmd.ExecuteReader();
while (oReader.Read())
{
//data.Add(new tmp_WatchList
//{
tmp_WatchList l = new tmp_WatchList();
l.id = int.Parse(oReader["id"].ToString());
l.Name = oReader.GetValue(1).ToString();
l.Crime = int.Parse(oReader.GetValue(2).ToString());
data.Add(l);
///});
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
con.Close();
}
}
}
and my stored procedure is:
ALTER PROCEDURE [dbo].[sp_CheckPersonList]
(#Name NVARCHAR(MAX) NULL)
AS
BEGIN
SELECT REPLACE(Name, '.', ''), Crime
FROM [dbo].[tmp_WatchList]
WHERE [Name] LIKE CONCAT('%', REPLACE(#Name, ' ', '%'), '%')
END
Can you tell me how it is done? Or is something wrong with my structure?
You are not opening the connection any where before calling the ExecuteReader, you need to open the database connection, following is the lineo of code to open the connection :
con.Open(); // open connection
SqlDataReader oReader = cmd.ExecuteReader(); // now execute SP
and you do not need finally block for closing the connection, as you are already applyuing the using block on your SqlConnection and SqlCommand which is converted by compiler in to try finally which takes care of disposing the resources and in case of SqlConnection closing the connection.
As other have pointed out, you need to Open the connection, and you can simplify your code removing the try/catch/finally and the explicit con.Close(), which you don't need since you are (corretcly) wrapping the connection within a using
Your code should be something like this (much cleaner than the original one after removing the try/catch/finally):
List<tmp_WatchList> data = new List<tmp_WatchList>();
using (SqlConnection con = new SqlConnection(conStr))
{
con.Open();
using (SqlCommand cmd = new SqlCommand("sp_CheckPersonList", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#Name", SqlDbType.NVarChar).Value = name;
SqlDataReader oReader = cmd.ExecuteReader();
while (oReader.Read())
{
tmp_WatchList l = new tmp_WatchList();
l.id = int.Parse(oReader["id"].ToString());
l.Name = oReader.GetValue(1).ToString();
l.Crime = int.Parse(oReader.GetValue(2).ToString());
data.Add(l);
}
}
}
If that code raises an exception, it will simply be forwarded to the caller, in a better way comparing to what you did with your throw new Exception(exc.Message), which will loose the original stack trace
Remove the unwanted code..Try Like this..
List<tmp_WatchList> data = new List<tmp_WatchList>();
SqlConnection con = new SqlConnection(conStr);
SqlCommand cmd=new SqlCommand();
cmd.CommmandText="sp_CheckPersonList";
cmd.CommandType = CommandType.Text;
con.Open();
cmd.Connection = con;
cmd.Parameters.AddWithValue("#Name",name);
SqlDataReader oReader = cmd.ExecuteReader();
while (oReader.Read())
{
tmp_WatchList l = new tmp_WatchList();
l.id = int.Parse(oReader["id"].ToString());
l.Name = oReader.GetValue(1).ToString();
l.Crime = int.Parse(oReader.GetValue(2).ToString());
data.Add(l);
}
oReader.Close();
Con.Close();
Related
I can't extract the values through a query and insert them into textboxes
Where am I going wrong?
Request.QueryString.Get("ID_Persona");
string query = "SELECT ID,Nome,Cognome,Email,CodiceFiscale FROM Persona WHERE ID = #id";
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["dbConnection"].ConnectionString))
{
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("#ID","");
cmd.Parameters.AddWithValue("#Nome", TextBox1.Text);
cmd.Parameters.AddWithValue("#Cognome", TextBox15.Text);
cmd.Parameters.AddWithValue("#Email", TextBox20.Text);
cmd.Parameters.AddWithValue("#CodiceFiscale", TextBox22.Text);
con.Open();
cmd.ExecuteNonQuery();
}
You need to use ExecuteReader to read values, something like this:
var connectionString = ConfigurationManager.ConnectionStrings["dbConnection"].ConnectionString;
string query = "SELECT ID,Nome,Cognome,Email,CodiceFiscale FROM Persona WHERE ID = #id";
using (SqlConnection con = new SqlConnection(connectionString))
{
using (var cmd = new SqlCommand(query, con))
{
cmd.Parameters.AddWithValue("#ID", Request.QueryString.Get("ID_Persona"));
con.Open();
using (var rdr = cmd.ExecuteReader())
{
if (rdr.Read())
{
//IDTextBox? = rdr["Id"].ToString(),
TextBox1.Text = rdr["Nome"].ToString(),
TextBox15.Text = rdr["Cognome"].ToString(),
TextBox20.Text= rdr["Email"].ToString(),
TextBox22.Text= rdr["CodiceFiscale"].ToString(),
}
}
}
}
You should use a ExecuteReader() instead of ExecuteNonQuery() since ExecuteNonQuery is meant for DML operations. Again, you need only the ID value to be passed then why you are passing unnecessary parameters to your query. Remove them all. An example below
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
Console.WriteLine(String.Format("{0}", reader["Email"]));
}
I can see several issues:
You should use ExecuteReader() instead of ExecuteNonQuery()
You should provide just 1 parameter - #ID; I doubt if it should have an empty value.
You should wrap IDisposable into using
Code:
string query =
#"SELECT ID,
Nome,
Cognome,
Email,
CodiceFiscale
FROM Persona
WHERE ID = #id";
using (SqlConnection con = new SqlConnection(...))
{
con.Open();
using SqlCommand cmd = new SqlCommand(query, con)
{
// I doubt if you want empty Id here.
// I've assumed you want to pass ID_Persona
cmd.Parameters.AddWithValue("#ID", Request.QueryString.Get("ID_Persona"));
using (var reader = cmd.ExecuteReader())
{
if (reader.Read())
{
TextBox1.Text = Convert.ToString(reader["Nome"]);
TextBox15.Text = Convert.ToString(reader["Cognome"]);
TextBox20.Text = Convert.ToString(reader["Email"]);
TextBox22.Text = Convert.ToString(reader["CodiceFiscale"]);
}
}
}
}
Well, I work little bit with C # and I'm starting to work with Database with C # now, I've googled in several places and I am unable to identify where it is wrong, everywhere say I need to open a connection, but it is already open .
SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\v11.0;Integrated Security=True;AttachDbFilename=C:\Users\Gustavo\Documents\Visual Studio 2013\Projects\hour\hour\Database1.mdf");
con.Open();
try
{
string query = "INSERT INTO [Table] (name, time) VALUES ('test',1)";
SqlCommand cmd = new SqlCommand(query);
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
Use using, takes care of the closing and disposal for you just in case you forget to do it explicitly. Put it inside the try, you have the connection open command outside the try so it wont catch any connection error. You probably want to look at parameterizing your command too.
using (SqlConnection conn = new SqlConnection(#"Data Source=(LocalDB)\v11.0;Integrated Security=True;AttachDbFilename=C:\Users\Gustavo\Documents\Visual Studio 2013\Projects\hour\hour\Database1.mdf"))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand("INSERT INTO [Table] (name, time) VALUES (#name,#time)", conn))
{
cmd.Parameters.AddWithValue("#name", "test");
cmd.Parameters.AddWithValue("#time", 1);
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
}
SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\v11.0;Integrated Security=True;AttachDbFilename=C:\Users\Gustavo\Documents\Visual Studio 2013\Projects\hour\hour\Database1.mdf");
try
{
string query = "INSERT INTO [Table] (name, time) VALUES ('test',1)";
SqlCommand cmd = new SqlCommand(query,con);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
you need to assign the command to the connection. eg:
private static void ReadOrderData(string connectionString)
{
string queryString =
"SELECT OrderID, CustomerID FROM dbo.Orders;";
using (SqlConnection connection = new SqlConnection(
connectionString))
{
//----
SqlCommand command = new SqlCommand(
queryString, connection);
//----
connection.Open();
SqlDataReader reader = command.ExecuteReader();
try
{
while (reader.Read())
{
Console.WriteLine(String.Format("{0}, {1}",
reader[0], reader[1]));
}
}
finally
{
// Always call Close when done reading.
reader.Close();
}
}
}
I keep getting this error
There is already an open datareader associated with this command which must be closed first.
at this line of code:
using (SqlDataReader rd = command.ExecuteReader())
I have tried to close all other SqlDataReader's in class but it didn't work.
public int SifreGetir(string pEmail) {
SqlCommand command = con.CreateCommand();
command.CommandText = #"SELECT Sifre FROM Kullanici WITH (NOLOCK) WHERE email=#email";
command.Parameters.Add("#email", SqlDbType.VarChar);
command.Parameters["#email"].Value = pEmail;
using (SqlDataReader rd = command.ExecuteReader())
{
rd.Read();
string pass = rd["Sifre"].ToString();
int p = Convert.ToInt32(pass);
return p;
}
}
Try implementing your code in the below format
using(SqlConnection connection = new SqlConnection("connection string"))
{
connection.Open();
using(SqlCommand cmd = new SqlCommand("your sql command", connection))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader != null)
{
while (reader.Read())
{
//do something
}
}
}
}
}
The using statement will ensure disposal of the objects at the end of the using block
try this:
public int SifreGetir(string pEmail) {
SqlConnection con = new SqlConnection("Your connection string here");
con.Open();
SqlDataAdapter da = new SqlDataAdapter();
DataSet ds = new DataSet();
SqlCommand command = new SqlCommand(#"SELECT Sifre FROM Kullanici WITH (NOLOCK) WHERE email=#email",con);
command.CommandType = CommandType.Text;
command.Parameters.Add("#email", SqlDbType.VarChar).Value = pEmail;
da.Fill(ds);
foreach(DataRow dr in ds.Tables[0].Rows)
{
string pass = dr["Sifre"].ToString();
int p = Convert.ToInt32(pass);
return p;
}
con.Close();
}
You have used Using Keyword for SQL Reader but There is nothing to take care of your command and connection object to dispose them properly. I would suggest to try disposing your Connection and command both objects by Using keyword.
string connString = "Data Source=localhost;Integrated " + "Security=SSPI;Initial Catalog=Northwind;";
using (SqlConnection conn = new SqlConnection(connString))
{
SqlCommand cmd = new;
cmd.CommandText = "SELECT ID, Name FROM Customers";
conn.Open();
using (SqlDataReader rd = command.ExecuteReader())
{
rd.Read();
string pass = rd["Sifre"].ToString();
int p = Convert.ToInt32(pass);
return p;
}
}
We use oracle database connection and our class database access does not have a dispose or close. It interferes with something or performance of the application? I saw this example:
string oradb = "Data Source=ORCL;User Id=hr;Password=hr;";
OracleConnection conn = new OracleConnection(oradb); // C#
conn.Open();
OracleCommand cmd = new OracleCommand();
cmd.Connection = conn;
cmd.CommandText = "select * from departments";
cmd.CommandType = CommandType.Text;
OracleDataReader dr = cmd.ExecuteReader();
dr.Read();
label1.Text = dr.GetString(0);
conn.Dispose();
And I realized that it opens the connection and then kills her. This is correct? Is there any other better?
I'm leaving my connection open and then ends up being closed for a while. I think that's it. This so wrong?
Use the Using statement with disposable objects. In particular with any kind of connection and datareaders
string oradb = "Data Source=ORCL;User Id=hr;Password=hr;";
using(OracleConnection conn = new OracleConnection(oradb))
using(OracleCommand cmd = new OracleCommand())
{
conn.Open();
cmd.Connection = conn;
cmd.CommandText = "select * from departments";
cmd.CommandType = CommandType.Text;
using(OracleDataReader dr = cmd.ExecuteReader())
{
dr.Read();
label1.Text = dr.GetString(0);
}
}
Here you could read about the Using statement and why it is important. Regarding the connection and readers, you should enclose the objects with the using statement to be sure that everything is properly closed and disposed when you exit from the using block ALSO in case of exceptions
I created the below method which i tested and does return the correct data. Where I am confused is what is the proper way to populate individual textboxes on a form with the results from this method?
Rather than using an objectdatasource and then binding a gridview to the objectdatasource that works but I need more freedom to customize the form.
public MemberDetails GetMemberDetail(int membershipgen)
{
SqlConnection con = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand("usp_getmemberdetail", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#MEMBERSHIPGEN", SqlDbType.Int, 5));
cmd.Parameters["#MEMBERSHIPGEN"].Value = membershipgen;
try
{
con.Open();
SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow);
reader.Read();
MemberDetails mem = new MemberDetails((int)reader["MEMBERSHIPGEN"], (string)reader["MEMBERSHIPID"], (string)reader["LASTNAME"],
(string)reader["FIRSTNAME"], (string)reader["SUFFIX"], (string)reader["MEMBERTYPESCODE"]);
reader.Close();
return mem;
}
catch (SqlException err)
{
throw new ApplicationException("Data error.");
}
finally
{
con.Close();
}
Something along the lines of:
var memberDetails = GetMemberDetail(12345);
textBox1.Text = memberDetails.Prop1;
textBox2.Text = memberDetails.Prop2;
...
Also I would refactor this method and make sure that I properly dispose disposable resources by wrapping them in using statements to avoid leaking unmanaged handles:
public MemberDetails GetMemberDetail(int membershipgen)
{
using (SqlConnection con = new SqlConnection(connectionString))
using (SqlCommand cmd = con.CreateCommand())
{
con.Open();
cmd.CommandText = "usp_getmemberdetail";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#MEMBERSHIPGEN", membershipgen);
using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
if (reader.Read())
{
return new MemberDetails(
reader.GetInt32(reader.GetOrdinal("MEMBERSHIPGEN")),
reader.GetString(reader.GetOrdinal("MEMBERSHIPID")),
reader.GetString(reader.GetOrdinal("LASTNAME")),
reader.GetString(reader.GetOrdinal("FIRSTNAME")),
reader.GetString(reader.GetOrdinal("SUFFIX")),
reader.GetString(reader.GetOrdinal("MEMBERTYPESCODE"))
);
}
return null;
}
}
}
Get the MemberDetails;
var memberDetails = GetMemberDetail(1);
Populate the textbox;
TextBox.Text = memberDetails.Property;
Jawaid outside of the correct answers that were provided below I would also set SqlConnection con = null; and
SqlCommand cmd = null; outside the try and inside the try put the following
con = new SqlConnection(connectionString);
this way if there is an Error when doing cmd.Parameters.Add -- you can trap that exception
also dispose of the reader object
if (reader != null)
{
((IDisposable)reader).Dispose();
// somthing like that .. do the same for con and cmd objects or wrap them in a using() {}
}
cmd = new SqlCommand("usp_getmemberdetail", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#MEMBERSHIPGEN", SqlDbType.Int, 5));
cmd.Parameters["#MEMBERSHIPGEN"].Value = membershipgen;