SqlDataReader with two tables - asp.net

I have a very simple code which fetches data from two tables
Inventory
Category
and displays them in two different GridView controls using SqlDataReader in the Page_Load event of an ASP.NET web application.
My point is, shouldn't SqlDataReader automatically traverse to the next table (Category) after reading the data from the previous table (Inventory)? Instead of using NextResult(), if I had reused the rdr object again for the next grid i.e. CategoryGridView without executing NextResult(), I'd get nothing (meaning it has moved on from Inventory?!)
So in a nutshell my question is where is the rdr pointing towards after reading from the first table (Inventory)?
using (SqlConnection con = new SqlConnection(CS))
{
SqlCommand cmd = new SqlCommand("Select * from tblInventory; Select * from tblCategory", con);
con.Open();
using (SqlDataReader rdr = cmd.ExecuteReader())
{
InventoryGridView.DataSource = rdr;
InventoryGridView.DataBind();
rdr.NextResult();
CategoryGridView.DataSource = rdr;
CategoryGridView.DataBind();
}
}

connection.Open();
SqlCommand command = new SqlCommand("Select * from tblInventory; Select * from tblCategory", connection);
using (SqlDataReader reader = command.ExecuteReader())
{
InventoryGridView.DataSource = reader;
InventoryGridView.DataBind();
while (reader.NextResult())
{
CategoryGridView.DataSource = reader;
CategoryGridView.DataBind();
}
}

Related

I want my table to display all record if no searches were found for a movie but am unsure how to do that

This is my code, tell me where to change because When I do search for a movie that is in a record it displays the result, but when it isn't I only get "Movie Not Found" as in the response.write.
enter image description hereSLNkq.png
I would suggest to put question as text/code instead.
For your case, I suggest you to work with datatable instead of datareader.
== With Datatable approach ==
SqlConnection con = new SqlConnection(constring);
SqlCommand cmd = new SqlCommand("IF EXISTS(SELECT * FROM Content WHERE MovieTitle=#MovieTitle) SELECT * FROM Content WHERE MovieTitle=#MovieTitle ELSE SELECT * FROM Content");
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#MovieTitle", MovieTitle.Text);
cmd.Connection = con;
con.Open();
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable("Result");
da.Fill(dt);
con.Close();
MovieResults.DataSource = dt;
MovieResults.DataBind();
Based on #Shai Cohen's comment, it would be better approach by using ExecuteDataReader if transaction is forward-only. Thanks #ShaiCohen for your comment.
== Without Datatable approach ==
SqlConnection con = new SqlConnection(constring);
SqlCommand cmd = new SqlCommand("IF EXISTS(SELECT * FROM Content WHERE MovieTitle=#MovieTitle) SELECT * FROM Content WHERE MovieTitle=#MovieTitle ELSE SELECT * FROM Content");
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#MovieTitle", MovieTitle.Text);
cmd.Connection = con;
con.Open();
MovieResults.DataSource = cmd.ExecuteReader();
MovieResults.DataBind();
con.Close();
Enjoy Coding (;

i want to use data reader & update statement at same time

here is code
String[] month=new String[12]{"January","February","March","April","May","June","July","August","September","Octomber","November","December"};
int day = DateTime.Now.Day;
int mon= DateTime.Now.Month;
mon = mon - 1; //because month array is with 0
Label1.Text = day.ToString();
if (day==21)
{
int j = 1;
SqlCommand cmd1 = new SqlCommand();
cmd1.Connection = MyConn;
cmd1.CommandText = "SELECT No_of_times,Dustbin_no from mounthly_data";
SqlDataReader MyReader = cmd1.ExecuteReader();
while (MyReader.Read())
{
String a = MyReader["No_of_times"].ToString();
String b = MyReader["Dustbin_no"].ToString();
SqlCommand cmd = new SqlCommand();
cmd.Connection = MyConn;
cmd.CommandText = "update Yearly_data set [" + month[mon] + "]='"+a+"' where Dustbin_no='"+b+"'"; //just see ["+month[mon+"] it's imp
i = cmd.ExecuteNonQuery();
}
MyReader.Close();
}
i got error as
There is already an open DataReader associated with this Command which must be closed first.
I think you should give us the rest of the code above this code block because I'm not sure how a ExecuteNonQuery is using up a datareader. But from what I can gather, what you probably want is to open two separate connections. Only one datareader can be open per connection at a time. Either you use two separate connections or you could maybe use a datatable/dataset for the result of both your queries.
EDIT: From the rest of your code, yes, using two connections would be the simplest answer. When a reader is open, the connection associated with it is dedicated to the command that is used, thus no other command can use that connection.
I would recommend using a DataTable as this OLEDB example shows:
public static void TrySomethingLikeThis()
{
try
{
using (OleDbConnection con = new OleDbConnection())
{
con.ConnectionString = Users.GetConnectionString();
con.Open();
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = con;
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT * FROM Customers";
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
foreach (DataRow row in dt.AsEnumerable())
{
cmd.CommandText = "UPDATE Customers SET CustomerName='Ronnie' WHERE ID = 4";
cmd.ExecuteNonQuery();
}
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}

Invalid attempt to call Read when reader is closed

I'm kind of struggling trying to get this datagrid to bind. Everytime I run my code, I get an error message stating, "Invalid attempt to call Read when reader is closed". I don't see where I am closing my reader. Can you please help me? My code for loading the datagrid is below:
protected void LoadGrid()
{
using (SqlConnection conn = new SqlConnection())
{
conn.ConnectionString = ConfigurationManager.ConnectionStrings["VTC"].ConnectionString;
conn.Open();
string sql = "select * from roi_tracking";
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
using (SqlDataReader sqlReader = cmd.ExecuteReader())
{
gridROI.DataSource = sqlReader;
gridROI.DataBind();
sqlReader.Dispose();
cmd.Dispose();
}
}
}
}
You can't use a SqlDataReader as a DataSource for a DataGrid.
From MSDN:
A data source must be a collection that implements either the
System.Collections.IEnumerable interface (such as
System.Data.DataView, System.Collections.ArrayList, or
System.Collections.Generic.List(Of T)) or the IListSource interface to
bind to a control derived from the BaseDataList class.
Datasource property:
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.basedatalist.datasource.aspx
SqlDataReader:
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.aspx
A common methodology to bind the query results to your datagrid would be to use a SqlDataAdapter to fill a DataTable or DataSet and then bind that to your DataGrid.DataSource:
protected void LoadGrid()
{
using (SqlConnection conn = new SqlConnection())
{
conn.ConnectionString = ConfigurationManager.ConnectionStrings["VTC"].ConnectionString;
conn.Open();
string sql = "select * from roi_tracking";
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = cmd;
adapter.Fill((DataTable)results);
gridROI.DataSource = results;
}
}
}
In addition to what pseudocoder said, you wouldn't want to bind to a SqlDataReader anyway: the connection to the database will remain open so long as the reader instance exists.
You definitely want to deserialize the data into some other disconnected data structure so that you release the connection back into the pool as quickly as possible.

Update in ASP.NET

I am using this code snippet to update values in my database :
SqlConnection con = new SqlConnection(#"Data Source=SAMA-PC\SQLEXPRESS;Initial Catalog=advCenter;Integrated Security=True");
string str = "sama#yahoo.com";
SqlCommand com2 = new SqlCommand("select [user_Account] from User in str where [user_Email]=sama#yahoo.com", con);
SqlCommand com = new SqlCommand("update User set [user_Account]=? WHERE [user_Email=#em]", con);
com.Parameters.AddWithValue("user_Account",str);
com.Parameters.AddWithValue("#em",str);
con.Open();
com.ExecuteNonQuery();
com2.ExecuteNonQuery();
con.Close();
but I get this error
Incorrect syntax near the keyword 'User'.
Line 40: com.ExecuteNonQuery();
"User" is a reserved word in SQL. Wrap the name of the table in square brackets to specify that it's the name of something:
[User]
Why are you using two separate SqlCommand objects?? Absolutely not needed..... I would try to either UPDATE or SELECT - don't mix two totally separate operations into a single call....
Also: you should use parametrized queries to avoid SQL injection attacks, and you should put your SqlConnection and SqlCommand objects into using blocks - try this:
string updateStmt =
"UPDATE dbo.[User] SET [user_Account] = #AccountValue WHERE [user_Email] = #UserEMail;";
using(SqlConnection con = new SqlConnection(#"Data Source=SAMA-PC\SQLEXPRESS;Initial Catalog=advCenter;Integrated Security=True"))
using(SqlCommand _cmd = new SqlCommand(updateStmt, con))
{
_cmd.Parameters.Add("#AccountValue", SqlDbType.VarChar, 100).Value = str;
_cmd.Parameters.Add("#UserEMail", SqlDbType.VarChar, 100).Value = str;
con.Open();
_cmd.ExecuteNonQuery();
con.Close();
}

How can I execute multiple database requests in ASP.NET C#?

In every ASP.NET application I have written, I would make number of request to the database before outputting the information onto the web page.
For example:
var DataTable1 = GetDataTable("Select * From Customers");
var DataTable2 = GetDataTable("Select * From Products");
var DataTable3 = GetDataTable("Select * From Orders");
As far as I'm aware, the code above would make 3 separate trips to the database and would do them one after the other.
Is there anyway I can gather together my parameterized SQL statements and make only 1 trip to the database server?
var SqlString = "SELECT * FROM Customers; SELECT * FROM Products; SELECT * FROM ORDERS;");
var ds = GetDataSet(SqlString);
var DataTable1 = ds.Tables(0);
var DataTable2 = ds.Tables(1);
var DataTable3 = ds.Tables(2);
My solution:
SqlConnection con = new SqlConnection("Server=CLASS-III-WKS10\\SQLEXPRESS;Initial
Catalog=wind;Integrated Security=True");
int[] id=new int[9];
int i = 0;
page_load()
{
con.Open();
SqlCommand cmd = new SqlCommand("select *from windmill", con);
SqlDataReader rd = cmd.ExecuteReader();
while (rd.Read())
{
id[i] = rd.GetInt32(9);
i++;
//MessageBox.Show(id.ToString());
}
rd.close();
SqlCommand cmd1 = new SqlCommand("Update windmill set State='Stopped',PmState='Not Available'where Id=0", con);
cmd1.ExecuteNonQuery();
}
Use semi-colons to separate SQL statements and reader.NextResult to get each set. Your code will end up looking something like this.
Using con As New SqlConnection
Using cmd As New SqlCommand("Select * From Customers; Select * From Products; Select * From Orders")
Using reader = cmd.ExecuteReader
Dim dt1 As DataTable
dt1.Load(reader)
reader.NextResult()
Dim dt2 As DataTable
dt2.Load(reader)
reader.NextResult()
Dim dt3 As DataTable
dt3.Load(reader)
End Using
End Using
End Using
Create a Thread class and place a method in that class which accept string query as input:
then create a Thread object and start the object.
Check this out http://msdn.microsoft.com/en-us/library/aa645740(VS.71).aspx

Resources