There is already an open datareader error when filling Gridviews - c#

I have looked at several posts already on trying to fix this issue and none of them are working.
I'm already using multiple active results.
I'm making sure to close the reader connections.
I'm using a different connection.
I'm using unique names for the reader, datatable, the reader, the command...
I am stuck.
The error is: There is already an open DataReader associated with this Command which must be closed first.
I have marked the error line with "*****error here *****".
Code:
protected void gridviewsched_RowDataBound(object sender, GridViewRowEventArgs e)
{
string nametime;
string name;
string time;
string initid;
string timeinitid = null;
GridView gridviewschedsub = (GridView)e.Row.FindControl("gridviewschedsub");
GridView gridviewschedcplt = (GridView)e.Row.FindControl("gridviewschedcplt");
using (SqlConnection con = new SqlConnection("Data Source=localhost\\SQLEXPRESS;AttachDbFilename=C:\\Users\\Public\\public website\\slDataBase.mdf;Integrated Security=True;Trusted_Connection=True; MultipleActiveResultSets=True;"))
{
con.Open();
DataTable dz = new DataTable();
dz.Columns.Add("age");
dz.Columns.Add("sex");
dz.Columns.Add("address");
if (e.Row.RowType == DataControlRowType.DataRow)
{
string id = gridviewsched.DataKeys[e.Row.RowIndex].Value.ToString();
using (var cmd = new SqlCommand("SELECT age,sex,address FROM precordTable WHERE Id='" + id + "'", con))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
//List<string> namedatelist = new List<string>();
while (reader.Read())
{
DataRow dr = dz.NewRow();
dr["age"] = reader[0].ToString();
dr["sex"] = reader[1].ToString();
dr["address"] = reader[2].ToString();
dz.Rows.Add(dr);
}
reader.Close();
}
gridviewschedsub.DataSource = dz;
gridviewschedsub.DataBind();
con.Close();
}
using (var cmd3 = new SqlCommand("SELECT name, initid FROM precordTable WHERE Id='" + id + "'", con))
{
con.Open();
using (SqlDataReader reader = cmd3.ExecuteReader())
{
List<string> namedatelist = new List<string>();
while (reader.Read())
{
name = reader["name"].ToString();
initid = reader["initid"].ToString();
time = DateTime.Now.ToString("MM-dd-yyyy");
time = Regex.Replace(time, "[^0-9a-zA-Z]+", "");
namedatelist.Add(name + time);
timeinitid = time + "$" + initid;
}
Session["timeinitid"] = timeinitid;
nametime = Regex.Replace(namedatelist[0].ToString(), "[^0-9a-zA-Z]+", "");
reader.Close();
}
}
var cmd2 = new SqlCommand("select case when exists((select * from [C:\\USERS\\PUBLIC\\PUBLIC WEBSITE\\SLDATABASE.MDF].INFORMATION_SCHEMA.tables where table_name = 'D" + timeinitid + "ou')) then 1 else 0 end", con);
if ((int)cmd2.ExecuteScalar() == 1)
{
string fQuery = "select item, scheduled from D" + timeinitid + "ou where 0 = 1";
string pQuery = "select item, scheduled from D" + timeinitid + "ou where initialed = '' and prescdr IS NULL and item != '';";
SqlDataAdapter sdyn = new SqlDataAdapter();
DataTable cpltTable = new DataTable();
cpltTable = GetData(pQuery);
gridviewschedcplt.DataSource = cpltTable;
gridviewschedcplt.DataBind();
con.Close();
}
else
{
return;
}
}
}
for (int j = 0; j < gridviewsched.Rows.Count; j++)
{
for (int i = 3; i < 9; i++)
{
gridviewsched.Rows[j].Cells[i].RowSpan = 2;
}
gridviewsched.Rows[j].Cells[2].RowSpan = 2;
}
}
private static DataTable GetData(string pQuery)
{
string schedtime;
string nowtime;
SqlDataAdapter sd1 = new SqlDataAdapter();
DataTable dTable = new DataTable();
using (SqlConnection conn = new SqlConnection("Data Source=localhost\\SQLEXPRESS;AttachDbFilename=C:\\Users\\Public\\public website\\slDataBase.mdf;Integrated Security=True;Trusted_Connection=True;MultipleActiveResultSets=True;"))
{
conn.Open();
SqlCommand cmd33 = new SqlCommand(pQuery, conn);
using (SqlDataReader reader99 = cmd33.ExecuteReader())
{
while (reader99.Read())
{
sd1.SelectCommand = cmd33;
***error here**** sd1.Fill(dTable);
DataRow newcpltTablerow = dTable.NewRow();
newcpltTablerow["item"] = reader99["item"].ToString();
dTable.Rows.Add(newcpltTablerow);
}
reader99.Close();
}
return dTable;
}
}

You do not need a SqlDataReader if you are using a SqldataAdapter. You are getting the error because you open a reader within an already open adapter. Do this instead (not compiled so tweak as needed and change the query to yours):
using (SqlConnection con = new SqlConnection(constring))
{
using (SqlCommand cmd = new SqlCommand("SELECT * FROM Customers", con))
{
cmd.CommandType = CommandType.Text;
using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
{
using (DataTable dt = new DataTable())
{
sda.Fill(dt);
dataGridView1.DataSource = dt;
}
}
}
}

cmd33.ExecuteReader can only be called once. You are executing it for each row.

Related

Error ExecuteNonQuery: Connection property has not been initialized

I am having a problem with the following code:
namespace Elite_Shop
{
public partial class Bill : Form
{
int j;
int total = 0;
SqlConnection sqlcon = new SqlConnection(#"Data Source=HP\SQLEXPRESS;Initial Catalog=EliteShop;Integrated Security=True ");
public Bill()
{
InitializeComponent();
}
public void get_value(int i)
{
j = i;
}
private void Bill_Load(object sender, EventArgs e)
{
if (sqlcon.State == ConnectionState.Open)
{
sqlcon.Close();
}
sqlcon.Open();
DataSet1 ds = new DataSet1();
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "Select * from Salesman_Table Where SMID="+j+"";
cmd.ExecuteNonQuery();
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds.DataTable1);
SqlCommand cmd2 = new SqlCommand();
cmd2.CommandType = CommandType.Text;
cmd2.CommandText = "Select * from Sale_Table Where OrderID=" + j + "";
cmd2.ExecuteNonQuery();
DataTable dt2 = new DataTable();
SqlDataAdapter da2 = new SqlDataAdapter(cmd2);
da2.Fill(ds.DataTable2);
da2.Fill(dt2);
foreach (DataRow dr2 in dt2.Rows)
{
total = total + Convert.ToInt32(dr2["Sub Total"].ToString());
}
SaleReport sr = new SaleReport();
sr.SetDataSource(ds);
sr.SetParameterValue("Grand Total", total.ToString());
crystalReportViewer1.ReportSource = sr;
}
}
}
When executed, the following error message is returned:
ExecuteNonQuery: Connection property has not been initialized.
How do I fix it?
You need to set the Connection property on the SqlCommand:
cmd.Connection = sqlcon;

How to delete multiple rows in C# using a SQL query?

I have code for deleting a row in C# using a SqlCommand. But I want to delete multiple rows. Can anyone help me with this? I am new to C#.
This is my code - please help. Thank you in advance.
foreach (DataGridViewRow dr in dataGrid1.SelectedRows)
{
SqlConnection con = new SqlConnection();
con.ConnectionString = #"Data Source=DDBULK10\SQLEXPRESS;Initial Catalog=MasterList; Integrated Security = True";
if (dr.Index > 0)
{
int selectedIndex = dataGrid1.SelectedRows[0].Index;
int rowID = int.Parse(dataGrid1[0, selectedIndex].Value.ToString());
string sql = "DELETE FROM ActiveUser WHERE EmpId = #EmpId";
SqlCommand deleteRecord = new SqlCommand();
deleteRecord.Connection = con;
deleteRecord.CommandType = CommandType.Text;
deleteRecord.CommandText = sql;
SqlParameter RowParameter = new SqlParameter();
RowParameter.ParameterName = "#EmpId";
RowParameter.SqlDbType = SqlDbType.Int;
RowParameter.IsNullable = false;
RowParameter.Value = rowID;
deleteRecord.Parameters.Add(RowParameter);
deleteRecord.Connection.Open();
deleteRecord.ExecuteNonQuery();
//deleteRecord.Connection.Close();
MessageBox.Show("Record Successfully Deleted");
SqlDataAdapter sda = new SqlDataAdapter("select * from ActiveUser", con);
DataTable dt = new DataTable();
sda.Fill(dt);
dataGrid1.DataSource = dt;
}
else if (dialogResult == DialogResult.No)
{
this.Refresh();
}
}
You can build a comma separated userid list like -
string strUserIds = string.Empty();
for(int i=0; i<dataGrid.Count;i++)
{
strUserIds = strUserIds +","+ dataGrid.SelectedRows[0].Cells[0].Value;
}
--Remove last unwanted comma from strUserIds
then execute sql query as "DELETE FROM EmployeeTbl WHERE UserID in (" + strUserIds + ")"
This will delete multiple records from table.
Just Make some changes in Your Coding !
Delete All Selected Rows
Run Your select * from ActiveUser
public void deldata()
{
foreach (DataGridViewRow dr in dataGrid1.SelectedRows)
{
SqlConnection con = new SqlConnection();
con.ConnectionString = #"Data Source=DDBULK10\SQLEXPRESS;Initial Catalog=MasterList; Integrated Security = True";
if (dr.Index > 0)
{
int selectedIndex = dataGrid1.SelectedRows[0].Index;
int rowID = int.Parse(dataGrid1[0, selectedIndex].Value.ToString());
string sql = "DELETE FROM ActiveUser WHERE EmpId = #EmpId";
SqlCommand deleteRecord = new SqlCommand();
deleteRecord.Connection = con;
deleteRecord.CommandType = CommandType.Text;
deleteRecord.CommandText = sql;
SqlParameter RowParameter = new SqlParameter();
RowParameter.ParameterName = "#EmpId";
RowParameter.SqlDbType = SqlDbType.Int;
RowParameter.IsNullable = false;
RowParameter.Value = rowID;
deleteRecord.Parameters.Add(RowParameter);
deleteRecord.Connection.Open();
deleteRecord.ExecuteNonQuery();
//deleteRecord.Connection.Close();
MessageBox.Show("Record Successfully Deleted");
}
else if (dialogResult == DialogResult.No)
{
this.Refresh();
}
}
}
public void showdata()
{
SqlDataAdapter sda = new SqlDataAdapter("select * from ActiveUser", con);
DataTable dt = new DataTable();
sda.Fill(dt);
dataGrid1.DataSource = dt;
}
You can use something like this; i didn't test the code but it should work if you create the parameters you need, before running code you have to create a type table, please see the link for details.
using (connection)
{
string sql ="Delete from YourTable t join #yourTypeTable i on t.id = i.Id:";
SqlCommand deleteCommand = new SqlCommand(sql, connection);
SqlParameter tvpParam = deleteCommand.Parameters.AddWithValue("#yourTypeTable", yourIdList);
tvpParam.SqlDbType = SqlDbType.Structured;
tvpParam.TypeName = "dbo.yourTypeTable";
deleteCommand.ExecuteNonQuery();
}

ASP.NET Gridview not outputting all data for a specific query

They're must be a minor error somewhere in my code that im not seeing as to why on my web page , the gridview only outputs one row when i know the query works/
Both rows from management studio
Only one row in ASP page
heres my c#
string AdminID = Request.QueryString["ID"];
string AdminsCurrentLocation = Request.QueryString["Location"];
//retrieve admin location
try
{
string connectionString = "Data Source=SQL5027.HostBuddy.com;Initial Catalog=DB_A05369_WATERQ;User Id=DB_A05369_WATERQ_admin;Password=waterqws1";
//
// Create new SqlConnection object.
//
using (SqlConnection connection5 = new SqlConnection(connectionString))
{
connection5.Open();
using (SqlCommand command = new SqlCommand("SELECT * FROM [DB_A05369_WATERQ].[dbo].[S_CONTROL] WHERE LOGIN = '" + AdminID + "'", connection5))
{
//
// Invoke ExecuteReader method.
//
using (SqlDataReader reader2 = command.ExecuteReader())
{
reader2.Read();
TempLocationIdbox.Text = (reader2["ALL_LOCATION_ACCESS"].ToString());
}
}
connection5.Close();
}
}
catch (Exception ex) { }
if(TempLocationIdbox.Text == "Y")
{
string strSQLconnection = "Data Source=SQL5027.HostBuddy.com;Initial Catalog=DB_A05369_WATERQ;User Id=DB_A05369_WATERQ_admin;Password=waterqws1";
SqlConnection sqlConnection = new SqlConnection(strSQLconnection);
SqlCommand sqlCommand = new SqlCommand("SELECT DISTINCT ACT.ROW_ID , ACT.CREATED , MEM.FIRST_NAME , MEM.LAST_NAME , LOC.NAME , CAT.NAME , SER.NAME , EMP.FIRST_NAME , EMP.LAST_NAME , SER.DURATION , ACT.CASH , COS.NAME , ACT.COMMENTS FROM " +
"S_ACTIVITY ACT, S_LOCATION LOC, S_CATEGORY CAT, S_EMPLOYEE EMP, S_SERVICE SER, S_COST_CODE COS, S_MEMBER MEM " +
"WHERE ACT.EMPLOYEE_ID = EMP.ROW_ID AND ACT.SERVICE_ID = SER.ROW_ID AND ACT.CATEGORY_ID = CAT.ROW_ID AND ACT.COST_CODE_ID = COS.ROW_ID AND ACT.LOCATION_ID = LOC.ROW_ID AND ACT.MEMBER_ID = MEM.ROW_ID", sqlConnection);
sqlConnection.Open();
SqlDataReader reader = sqlCommand.ExecuteReader();
//collect rowID
string retrievedROWID = "";
if (reader.HasRows)
{
reader.Read();
string temp1 = reader["ROW_ID"].ToString();
retrievedROWID = temp1;
GridView1.DataSource = reader;
GridView1.DataBind();
}
sqlConnection.Close();
}
else if (TempLocationIdbox.Text == "N")
{
string strSQLconnection1 = "Data Source=SQL5027.HostBuddy.com;Initial Catalog=DB_A05369_WATERQ;User Id=DB_A05369_WATERQ_admin;Password=waterqws1";
SqlConnection sqlConnection1 = new SqlConnection(strSQLconnection1);
SqlCommand sqlCommand1 = new SqlCommand("SELECT * FROM S_LOCATION WHERE NAME = '" + AdminsCurrentLocation + "'", sqlConnection1);
sqlConnection1.Open();
string locationrowID = "";
SqlDataReader reader12 = sqlCommand1.ExecuteReader();
if (reader12.HasRows)
{
reader12.Read();
locationrowID = reader12["ROW_ID"].ToString();
}
sqlConnection1.Close();
string strSQLconnection = "Data Source=SQL5027.HostBuddy.com;Initial Catalog=DB_A05369_WATERQ;User Id=DB_A05369_WATERQ_admin;Password=waterqws1";
SqlConnection sqlConnection = new SqlConnection(strSQLconnection);
SqlCommand sqlCommand = new SqlCommand("SELECT DISTINCT ACT.ROW_ID , ACT.CREATED , MEM.FIRST_NAME , MEM.LAST_NAME , LOC.NAME , CAT.NAME , SER.NAME , EMP.FIRST_NAME , EMP.LAST_NAME , SER.DURATION , ACT.CASH , COS.NAME , ACT.COMMENTS FROM "+
"S_ACTIVITY ACT, S_LOCATION LOC, S_CATEGORY CAT, S_EMPLOYEE EMP, S_SERVICE SER, S_COST_CODE COS, S_MEMBER MEM "+
"WHERE ACT.EMPLOYEE_ID = EMP.ROW_ID AND ACT.SERVICE_ID = SER.ROW_ID AND ACT.CATEGORY_ID = CAT.ROW_ID AND ACT.COST_CODE_ID = COS.ROW_ID AND "+
"ACT.LOCATION_ID = '"+ locationrowID + "' AND ACT.MEMBER_ID = MEM.ROW_ID AND LOC.NAME = '"+ AdminsCurrentLocation + "'", sqlConnection);
sqlConnection.Open();
SqlDataReader reader = sqlCommand.ExecuteReader();
//collect rowID
string retrievedROWID = "";
if (reader.HasRows)
{
reader.Read();
string temp1 = reader["ROW_ID"].ToString();
retrievedROWID = temp1;
GridView1.DataSource = reader;
GridView1.DataBind();
}
sqlConnection.Close();
}
What stumps me is that my other query is working fine for the case where TempLocationIdbox.Text == "Y"...
Thanks , any help would be much appreciated.
Instead of using if (reader.HasRows) you need to use while (reader.Read()).Also created some kind of collection for example List<T> and populate it with results inside the while loop.Then outside the loop set the DataSource of the GridView control to point to List<T>.Here's a complete example:
public class Activity
{
public int RowID { get; set; }
public DateTime Created { get; set; }
public string FirstName { get; set; }
}
public partial class UsingSqlDataReader : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
this.GetData();
}
}
private void GetData()
{
string cs = ConfigurationManager.ConnectionStrings["connectionString"].ConnectionString;
var activities = new List<Activity>();
using (var con = new SqlConnection(cs))
{
using(var cmd = new SqlCommand("SELECT ACT.ROW_ID,ACT.CREATED,ACT.FIRST_NAME FROM [dbo].[S_ACTIVITY] ACT", con))
{
cmd.CommandType = System.Data.CommandType.Text;
con.Open();
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var activity = new Activity();
activity.RowID = Convert.ToInt32(reader["ROW_ID"]);
activity.Created = DateTime.Parse(reader["CREATED"].ToString());
activity.FirstName = Convert.ToString(reader["FIRST_NAME"]);
activities.Add(activity);
}
}
}
}
GridView1.DataSource = activities;
GridView1.DataBind();
}
}
Output:
A better solution would be to put your in-line query in a stored proc and execute the stored proc.
You could also bring it in a dataset and bind the gridview with that. but that is completely your choice.
In-line queries are very error prone and results could be unpredictable hence refrain using that.

Deleting selected row from datagridview and database

I am writing this code for deleting selected row from datagridview and database at a time.
but i got the error in "deleteButton.Click"
deleteButton.Click += new System.EventHandler(this.DeleteRecord);
private DeleteRecord(object sender, EventArgs e)
{
foreach(DataGridViewRow row in DataGridView1.SelectedRows)
{
int rowIdToDelete = row.Cells[ID].Value;
using (OleDbConnection conn = new OleDbConnection(connectionString))
{
string query = "DELETE FROM [Record] WHERE ID = " + rowIdToDelete;
conn.Open();
using (OleDbCommand cmd = new OleDbCommand(query, conn))
{
using (OleDbDataAdapter adapter = new OleDbDataAdapter(query, conn))
{
DataTable ds = new DataTable();
adapter.Update(ds);
dataGridView.DataSource = ds;
cmd.ExecuteNonQuery();
}
}
}
}
}
Wrap rowIdToDelete within quotes.
string query = "DELETE FROM [Record] WHERE ID = " + "'rowIdToDelete'";
Also if ID is column name with add double quotes,
int rowIdToDelete = row.Cells["ID"].Value;

Unable to compare the columns in SqlBulkCopy

Here is my code:
protected void Button1_Click(object sender, EventArgs e)
{
string strFileType = System.IO.Path.GetExtension(FileUpload1.FileName).ToString().ToLower();
string strFileName = FileUpload1.PostedFile.FileName.ToString();
FileUpload1.SaveAs(Server.MapPath("~/Import/" + strFileName + strFileType));
string strNewPath = Server.MapPath("~/Import/" + strFileName + strFileType);
string excelConnectionString = String.Format(#"Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source="+strNewPath +"; Extended Properties=Excel 8.0;");
//string excelConnectionString = String.Format(#"Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=C:\\myFolder\\Book1.xls;" + "Extended Properties=Excel 8.0;");
// Create Connection to Excel Workbook
using (OleDbConnection connection = new OleDbConnection(excelConnectionString))
{
OleDbCommand command = new OleDbCommand("Select ID,Data FROM [Sheet1$]", connection);
connection.Open();
// Create DbDataReader to Data Worksheet
using (DbDataReader dr = command.ExecuteReader())
{
// SQL Server Connection String
string sqlConnectionString = "Data Source=DITSEC3;Initial Catalog=test;Integrated Security=True";
con.Open();
DataTable dt1 = new DataTable();
string s = "select count(*) from ExcelTable";
string r = "";
SqlCommand cmd1 = new SqlCommand(s, con);
try
{
SqlDataAdapter da1 = new SqlDataAdapter(cmd1);
da1.Fill(dt1);
}
catch { }
int RecordCount;
RecordCount = Convert.ToInt32(cmd1.ExecuteScalar());
r = RecordCount.ToString();
Label1.Text = r;
con.Close();
int prv = Convert.ToInt32(r);
//matching columns
//SqlBulkCopyColumnMapping mapping1 = new SqlBulkCopyColumnMapping("id", "ida");
//SqlBulkCopyColumnMapping mapping2 = new SqlBulkCopyColumnMapping("data", "dataa");
// Bulk Copy to SQL Server
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(sqlConnectionString))
{
bulkCopy.DestinationTableName = "ExcelTable";
bulkCopy.WriteToServer(dr);
}
con.Open();
DataTable dt = new DataTable();
s = "select count(*) from ExcelTable"; r = "";
SqlCommand cmd = new SqlCommand(s, con);
try
{
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
}
catch { }
RecordCount = Convert.ToInt32(cmd.ExecuteScalar());
r = RecordCount.ToString(); Label1.Text = r;
con.Close();
int ltr = Convert.ToInt32(r);
if (prv == ltr)
{
Label1.Text = "No records Added";
}
else
{
Label1.Text = "Records Added Successfully !";
}
}
}
I know I need to add something like:
SqlBulkCopyColumnMapping mapping1 = new SqlBulkCopyColumnMapping("id", "ida");
SqlBulkCopyColumnMapping mapping2 = new SqlBulkCopyColumnMapping("data", "dataa");
but I am not sure where I am supposed to add it in the above code
The column mappings are to be added to the bulkCopy.ColumnsMappings collection:
var mapping1 = new SqlBulkCopyColumnMapping("id", "ida");
bulkCopy.ColumnMappings.Add(mapping1);
You do the mapping before you execute the WriteToServer call.
The MSDN documentation of SqlBulkCopyColumnMapping has further documentation and an example.

Categories