Loop inside loop for .Net C# - c#

I want to retrieve all User_id's next after my entered User_id referencing each other from the table by Reference_id, the code below gives the exact result but it retrieves all User_id's from "2001 to 2005".
I want if i enter the "2002" as User_id from a textbox then it must retrieve from "2003 - 2005"
Table_xyz column User_id have value= 2001, 2002, 2003, 2004, 2005
Table_xyz column Reference_id have value= 2000, 2001, 2002, 2003, 2004
var gCmd = new SqlCommand(#"SELECT User_id FROM Table_xyz", nCon);
SqlDataAdapter Sda = new SqlDataAdapter(gCmd);
DataTable Dt = new DataTable();
Sda.Fill(Dt);
for (int i = 0; i < Dt.Rows.Count; i++)
{
string referenceid = Dt.Rows[i]["User_id"].ToString();
var gCmd1 = new SqlCommand(#"SELECT User_id FROM Table_xyz
WHERE Reference_id = '" + referenceid + "'", nCon);
SqlDataAdapter Sda1 = new SqlDataAdapter(gCmd1);
DataTable Dt1 = new DataTable();
Sda1.Fill(Dt1);
Response.Write(referenceid);
}
I tried adding "SELECT User_id FROM Table_xyz WHERE User_id = '2001'" to the first command but it returns only a single value where User_id matched "2001"

This is the easiest solution. But consider refactoring your code or thinking on another approach, this is not perfomatic. Also consider using parameters on you sql command.
string initialId = Dt.Rows[0]["ID"].ToString();
do
{
string dCmd = "SELECT ID FROM TableA WHERE Reference_ID = '" + initialId + "'";
SqlDataAdapter dSda = new SqlDataAdapter();
dSda.SelectCommand = new SqlCommand(dCmd, nCon);
DataTable dDt = new DataTable();
dSda.Fill(dDt);
for (int i = 0; i < dDt.Rows.Count; i++)
{
initialId = dDt.Rows[i]["ID"];
Response.Write(dDt.Rows[i]["ID"]);
}
}
while(dDt.Rows.Count > 0)

You can try this solution, in first you can get all distinct Refrence_ID and based on that you can loop to get IDs
var gCon = ConfigurationManager.ConnectionStrings["myCon"].ConnectionString;
using (var nCon = new SqlConnection(gCon))
{
try
{
nCon.Open();
String cmd = "SELECT DISTINCT Refrence_ID FROM TableA";
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand(cmd, nCon);
DataTable Dt = new DataTable();
adapter.Fill(Dt);
for (int count = 0; count < Dt.Rows.Count(); count++)
{
string dCmd = "SELECT ID FROM TableA WHERE Reference_ID = '" + dt.Rows[count]["Refrence_ID"] + "'";
SqlDataAdapter dSda = new SqlDataAdapter();
dSda.SelectCommand = new SqlCommand(dCmd, nCon);
DataTable dDt = new DataTable();
dSda.Fill(dDt);
for (int i = 0; i < dDt.Rows.Count; i++)
{
Response.Write(dDt.Rows[i]["Distributor_ID"]);
}
}
}
catch (Exception e)
{
Response.Write(e.ToString());
}
finally { nCon.Close(); }
}

Thanks to all of you my friends for the effort to help me but unfortunately that didn't solved the main issue.
After lot's of research for the same i got my answer at "Recursive command", so finally my code is below
string value = "2723022"; // <== any reference id from Reference_id column
String gCmd = "SELECT DISTINCT Reference_id FROM myTable WHERE User_id >'" + value + "'";
SqlDataAdapter Sda = new SqlDataAdapter();
Sda.SelectCommand = new SqlCommand(gCmd, nCon);
DataTable Dt = new DataTable();
Sda.Fill(Dt);
for (int count = 0; count < Dt.Rows.Count; count++)
{
string dCmd = "SELECT User_id FROM dEmo_aCcounts WHERE Reference_id = '" + Dt.Rows[count]["Reference_id"] + "'";
SqlDataAdapter dSda = new SqlDataAdapter();
dSda.SelectCommand = new SqlCommand(dCmd, nCon);
DataTable dDt = new DataTable();
dSda.Fill(dDt);
for (int i = 0; i < dDt.Rows.Count; i++)
{
Response.Write(dDt.Rows[i]["User_id"]);
}
}

Related

SQL Values to integers

I'm trying to compare values in a database that are updated every time a user logs in. When I execute a query with the given code nothing happens. However if I give it a value of say (where Attempt >10) it works where am I going wrong?
private void User_Tick(object sender, EventArgs e)
{
SqlConnection con13 = new SqlConnection("Data Source = *** ")
SqlDataAdapter SDA2 = new SqlDataAdapter("SELECT [User],[Login],[number1],[number2],[number3],[Alertcount] FROM Users.dbo.[Email] where [Alertcount] = 1 and [Alertcount] !=2", con13);
DataTable Users = new DataTable();
DataTable DATA2 = new DataTable();
SDA2.Fill(DATA2);
dataGridView2.DataSource = DATA2;
foreach (DataGridViewRow dr in dataGridView2.Rows)
{
string col2 = 1.Cells["User"].Value.ToString();
string col1 = 1.Cells["Login"].Value.ToString();
string col3 = 1.Cells["number1"].Value.ToString();
string col4 = 1.Cells["number2"].Value.ToString();
string col5 = 1.Cells["number3"].Value.ToString();
string col6 = 1.Cells["Alertcount"].Value.ToString();
var mine = Convert.ToInt32(col3);
var mine2 = Convert.ToInt32(col5);
SqlConnection CON2 = new SqlConnection("Data Source = ***")
CON2.Open();
SqlDataAdapter SDA = new SqlDataAdapter("SELECT [User],[Login],[Attempt] FROM User.dbo.Actions where [Attempt] > '"+mine+ "' and [Attempt] < '" + mine2 + "'", CON2);
DataTable DATA = new DataTable();
SDA.Fill(DATA);
dataGridView1.DataSource = DATA;
}
}
If column Attempt is an integer (as evident from the fact that Attempt < 10 runs), you need not pass comparison values to it in string. So your query should be like this:
SqlDataAdapter SDA = new SqlDataAdapter("SELECT [User],[Login],[Attempt] FROM User.dbo.Actions where [Attempt] > "+mine+ " and [Attempt] < " + mine2 , CON2);
I would suggest you to debug such errors in future by creating a query variable and then running the query in SQL manually to see what the error is. You could do something like this:
var query = "SELECT [User],[Login],[Attempt] FROM User.dbo.Actions where [Attempt] > "+mine+ " and [Attempt] < " + mine2 ;
SqlDataAdapter SDA = new SqlDataAdapter(query , CON2);
nothing happens - not enough information for correct answer. If actually nothing happens, then remove all try catch blocks you have around code and run application again. Then if something wrong you will get very useful information about what gone wrong in the form of Exception.
However, problem seems is that you passing wrong data to database query.
Always use SqlParameter for passing dynamic data to the query. SqlParameter have type which you can set to correspondent type of column you want operate on. Also SqlParameter will protect you from sql injection.
Use using for disposable objects when ever it possible (read "always")
var emailQuery =
#"SELECT [User] ,[Login] ,[number1] ,[number2] ,[number3] ,[Alertcount]
FROM Users.dbo.[Email]
WHERE [Alertcount] = 1
AND [Alertcount] !=2"; // Useless condition, because Alertcount already = 1
using(var connection2 = new SqlConnection("Data Source = *** "))
using(var adapter2 = new SqlDataAdapter(emailQuery, connection1))
{
var data2 = new DataTable();
adapter2.Fill(data2);
dataGridView2.DataSource = data2;
}
var actionsQuery =
#"SELECT [User] ,[Login] ,[Attempt]
FROM User.dbo.Actions
WHERE Attempt > #Mine AND Attempt < #Mine2";
foreach (var row in dataGridView2.Rows)
{
var mine = (int)row.Cells["number1"].Value; // it is already integer, just cast it
var mine2 = (int)row.Cells["number3"].Value;
using(var connection1 = new SqlConnection("Data Source = *** "))
using(var adapter1 = new SqlDataAdapter(actionsQuery, connection1))
{
var parameters = new[]
{
new SqlParameter
{
ParameterName = "#Mine",
SqlDbType = SqlDbType.Int,
Value = mine
},
new SqlParameter
{
ParameterName = "#Mine2",
SqlDbType = SqlDbType.Int,
Value = mine2
}
};
adapter1.SelectCommand.Parameters.AddRange(parameters);
var data1 = new DataTable();
adapter.Fill(data1);
dataGridView1.DataSource = data1
}
}

C# query and string coding error

I tried to get 4 names from first table and check how frequent 4 of the names appeared in each of another 20 groups and then update it on groupevenfrequency. However, I have encountered error on this coding. Appreciate if someone can assist. Thanks.
From this coding, why str[1] and str[2] and str[3] and str[4] is same teachername? But the sql command SELECT DISTINCT is already resulted 4 different teachers. Please advice.
dbConnect = new SQLiteConnection("Data Source=school.db;Version=3;");
dbConnect.Open();
cmd = new SQLiteCommand();
cmd = dbConnect.CreateCommand();
cmd.CommandText = "SELECT DISTINCT Teacher_Name from " + myTeacher + " Order by Sum_Weekly_Credit desc LIMIT 4";
DataTable dt = new DataTable();
SQLiteDataAdapter da = new SQLiteDataAdapter(cmd);
da.Fill(dt);
string[] str = new string[5];
for (int i = 1; i <= 4; i++)
{
foreach (DataRow dr in dt.Rows)
{
str[i] = dr["Teacher_Name"].ToString();
cmd.ExecuteNonQuery();
}
}
dbConnect.Close();
dbConnect = new SQLiteConnection("Data Source=school.db;Version=3;");
dbConnect.Open();
cmd2 = new SQLiteCommand();
cmd2 = dbConnect.CreateCommand();
cmd3 = new SQLiteCommand();
cmd3 = dbConnect.CreateCommand();
for (int j = 1; j <= 20; j++)
{
cmd2.CommandText = "SELECT Subject FROM Group_Even_" + j + " WHERE Teacher_Name = #Teacher_Name1 OR Teacher_Name = #Teacher_Name2 OR Teacher_Name = #Teacher_Name3 OR Teacher_Name = #Teacher_Name4";
cmd2.Parameters.AddWithValue("#Teacher_Name1", str[1]);
cmd2.Parameters.AddWithValue("#Teacher_Name2", str[2]);
cmd2.Parameters.AddWithValue("#Teacher_Name3", str[3]);
cmd2.Parameters.AddWithValue("#Teacher_Name4", str[4]);
DataTable dt2 = new DataTable();
SQLiteDataAdapter da2 = new SQLiteDataAdapter(cmd2);
da2.Fill(dt2);
if (dt2.Rows.Count > 0)
{
int TempCountFrequency = dt2.Rows.Count;
cmd2.CommandText = "UPDATE GroupEvenFrequency SET GroupEven_Frequency = #GroupEven_Frequency WHERE GroupEven_Name = Group_Even_" + j + "";
cmd2.Parameters.AddWithValue("#GroupEven_Frequency", TempCountFrequency);
cmd2.ExecuteNonQuery();
}
else
{
continue;
}
}
The code you have here looks wrong....
for (int i = 1; i <= 4; i++)
{
foreach (DataRow dr in dt.Rows)
{
str[i] = dr["Teacher_Name"].ToString();
cmd.ExecuteNonQuery();
}
}
Surely you are expecting the dt.Rows to contain the 4 names you are interested in? So why have the outer loop.
So shouldn't it be more like...
string[] str = new string[5];
int i = 1;
foreach (DataRow dr in dt.Rows)
{
str[i] = dr["Teacher_Name"].ToString();
i++;
}
But as others have pointed out your overall approach could do with a rethink. The code won't cater for the fact that you might not have 4 distinct teacher names

There is already an open datareader error when filling Gridviews

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.

Can help me to make Auto Generate ID?

I have form want to Auto Generate that ID from Primary Key
so that code like that
private void setidphoto()
{
DataTable dt = con.FillTable("SELECT IDPhoto FROM Produksi ORDER BY IDPhoto DESC");
if (dt.Rows.Count == 0)
{
txtIdPhoto.Text = "PH001";
}
else {
string temp = dt.Rows[0][0].ToString();
int IDplus= int.Parse(temp.Substring(2)) + 1;
string NewID = String.Format("PH{0:000}", IDPlus);
txtIdPhoto.Text = NewID;
}
}
The Error is con.FillTable cant compile or run it, can you help me
Try this
SqlConnection con = new SqlConnection("yourconnectionstringhere");
SqlCommand com = new SqlCommand("SELECT IDPhoto FROM Produksi ORDER BY IDPhoto DESC", con);
SqlDataAdapter adp = new SqlDataAdapter(com);
DataTable dt = new DataTable();
add.SelectCommand = com;
adp.Fill(dt);

How to display all Database data in Grid View using Data Table?

I have 5 data in my datatbase, these data I want to display in a gridView using Data Table. But my code displays only the last binded data in GridView? My code is. Please point out the mistake?
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString);
SqlCommand cmd = new SqlCommand("select Date from MusterRoll where EmpCode='"+code+"' and Month='1' and Year='2015'", conn);
SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
sda.Fill(ds);
var rows = ds.Tables[0].Rows;
foreach (DataRow row in rows)
{
string date1 = Convert.ToString(row["Date"]);
DateTime date2 = Convert.ToDateTime(date1);
SqlCommand cmd1 = new SqlCommand(" select TOP 1 m.EmpCode,m.NOH,m.OT,m.Late,m.Early,convert(varchar(10),m.Date,103)AS DATE,convert(varchar(10),s1.Shiftname,103)AS Shift From ShiftChange s,ShiftType s1,MusterRoll m WHERE s1.ShiftID=s.NShiftID and '" + date2 + "'>=Fromdate and Todate>='" + date2 + "' and m.Month = '1' and m.date='"+date2+"' and m.EmpCode='Neena' order by Todate desc", conn);
SqlDataAdapter sda1 = new SqlDataAdapter(cmd1);
DataTable dt = new DataTable();
sda1.Fill(dt);
//var rows1 = ds.Tables[0].Rows;
for (int rowIndex = 0; rowIndex < dt.Rows.Count; rowIndex++)
{
DataRow rpw = dt.Rows[rowIndex];
string EmpCode = rpw.Field<string>("EmpCode");
string NOH = rpw.Field<string>("NOH");
string OT = rpw.Field<string>("OT");
string Latae = rpw.Field<string>("Late");
string Early = rpw.Field<string>("Early");
string date3 =rpw.Field<string>("Date");
string Shift = rpw.Field<string>("Shift");
gvSingleemp.Visible = true;
gvSingleemp.DataSource = dt;
gvSingleemp.DataBind();
}
}
In my shiftChange table there is no Field for date instead of that I have fromDate and ToDate.I want display employee shifft according to MusterRoll table date. So that first I selected MusteRoll date nd checkrd this date exist in between ShiftChange FromDate and ToDate if exist show the Shift
You are databinding the GridView in a loop. You don't need the loop, just bind it to the DataTable:
SqlDataAdapter sda1 = new SqlDataAdapter(cmd1);
DataTable dt = new DataTable();
sda1.Fill(dt);
gvSingleemp.DataSource = dt;
gvSingleemp.DataBind();
I still think that you don't need those loops at all. I guess that you want to select all records from EmpDetails where the EmpCode = code and MusterRoll.Month='1' and MusterRoll.Year='2015'. Then you only need one sql query to fill one DataTable which can be used as DataSource for gvSingleemp. Is that correct?
If so, this should work (note that i use the using statement and sql-parameters):
DataTable tblData = new DataTable();
string sql = #"SELECT ed.EmpCode,ed.Name,ed.Age,ed.Date
FROM MusterRoll mr
INNER JOIN EmpDetails ed
ON mr.Date = ed.Date
WHERE mr.EmpCode=#EmpCode AND mr.Month=1 AND mr.Year=2015";
using(var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString))
using(var sda = new SqlDataAdapter(sql, conn))
{
var codeParam = new SqlParameter("#EmpCode", SqlDbType.VarChar).Value = code; // change type accordingly
sda.SelectCommand.Parameters.Add(codeParam);
sda.Fill(tblData); // no need for conn.Open/Close with SqlDataAdapter.Fill
}
gvSingleemp.Visible = true;
gvSingleemp.DataSource = tblData;
If you don't want to join the tables you can also use EXISTS:
string sql = #"SELECT ed.EmpCode, ed.Name, ed.Age, ed.Date
FROM EmpDetails ed
WHERE EXISTS
(
SELECT 1 FROM MusterRoll mr
WHERE mr.EmpCode = #EmpCode
AND mr.Month = 1 AND mr.Year=2015
AND mr.Date = ed.Date
)";
You dont have to use loop to bind the DT to GridView :
SqlCommand cmd1 = new SqlCommand(" select EmpCode,Name,Date,Age from EmpDetails where CompanyID='1'", conn);
SqlDataAdapter sda1 = new SqlDataAdapter(cmd1);
DataTable dt = new DataTable();
sda1.Fill(dt);
gvSingleemp.DataSource =dt;
gvSingleemp.DataBind();
SqlDataAdapter Da = new SqlDataAdapter(cmd);
DataTable data = new DataTable();
Da.Fill(data);
gvSingleemp.DataSource = data;
gvSingleemp.DataBind();

Categories