C# query and string coding error - c#

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

Related

SQL Server : convert Into prepared statement

The folllowing code is vulnerable to SQL injection and I am trying to correct the code of previous developer; he used DataTable to further use query - how do I use prepare statement along with data table?
string data = "";
int i = 1;
cmd = new SqlCommand("select * from maincategory where isactive=1 and id in (select catid from productmaster where isactive=1)", con);
con.Open();
DataTable dt = new DataTable();
dt.Load(cmd.ExecuteReader());
con.Close();
if (dt.Rows.Count > 0)
{
data += "<ul>";
foreach (DataRow DR in dt.Rows)
{
data += "<li><a href='product.aspx?cid="+DR["id"]+"'>" + DR["catname"] + "</a></li>";
}
data += " </ul>";
}
lblpartners.Text = data;
The code that I tried:
public void show()
{
string data = "";
int i = 1;
cmd = new SqlCommand("select * from maincategory where isactive=#val1 and id in (select catid from productmaster where isactive=#val2)", con);
con.Open();
cmd.Parameters.AddWithValue("#val1", 1);
cmd.Parameters.AddWithValue("#val2", 1);
DataTable dt = new DataTable();
dt.Load(cmd.Prepare());
con.Close();
if (dt.Rows.Count > 0)
{
data += "<ul>";
foreach (DataRow DR in dt.Rows)
{
data += "<li><a href='product.aspx?cid="+DR["id"]+"'>" + DR["catname"] + "</a></li>";
}
data += " </ul>";
}
lblpartners.Text = data;
}
SqlCommand.Prepare doesn't return an IDataReader, it's a void method. DataReader.Load() requires an IDataReader object.
Perhaps you meant dt.Load(cmd.ExecuteReader())?

Loop inside loop for .Net 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"]);
}
}

how to handle Datarow DBNull

The following code return empty cells for the ones who are stored as text" Number Stored as Text" How can I get the value of these cells ?
string connectionString = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fileName + ";Extended Properties='Excel 8.0;HDR=yes;IMEX=2';");
foreach (var sheetName in GetExcelSheetNames(connectionString))
{
using (OleDbConnection con1 = new OleDbConnection(connectionString))
{
var dt = new DataTable();
string query = string.Format("SELECT * FROM [{0}]", sheetName);
con1.Open();
OleDbDataAdapter adapter = new OleDbDataAdapter(query, con1);
adapter.Fill(dt);
for (int i = 1; i < dt.Rows.Count; i++)
{
for (int j = 1; j < dt.Columns.Count; j ++)
{
MessageBox.Show(dt.Rows[0][j].GetType().ToString());
}
}
var cell = dt.Rows[0][j] == System.DBNull.Value ? "null...", dt.Rows[0][j];
Use IMEX=1 for mixed types in connection string.

How add row to gridview in WPF using C#

How add rows to grid-view in WPF,when the grid-view already contains the data.,
SqlCommand cmd = new SqlCommand("SELECT CName'Name',CLocation'Location',VehicleNo,GasName,Quantity,OrderDate,SupplyDays'Dispatching Day' FROM View_DailyPlanning "
+ " where (OrderDate='" + DateTime.Now.ToShortDateString() + "' and SupplyDays='" + day + "')", DataAccessBase.GetSqlConnection());
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable("View_DailyPlanning");
da.Fill(dt);
grid_display.AutoGenerateColumns = true;
grid_display.ItemsSource = dt.DefaultView;
grid_display.Columns[0].Width = 100;
grid_display.Columns[1].Width = 150;
grid_display.Columns[2].Width = 100;
grid_display.Columns[3].Width = 100;
grid_display.Columns[4].Width = 100;
grid_display.Columns[5].Width = 100;
grid_display.Columns[6].Width = 100;
grid_display.Items.Add(new Item() { CName = "Someone4", CLocation = "Madivala",VehicleNo="TN2345",Quantity="26",Date="10/07/2014",SupplyDays="Friday"});
ction());
SqlCommand cmd = new SqlCommand("SELECT CName'Name',CLocation'Location',VehicleNo,GasName,Quantity,OrderDate,SupplyDays'Dispatching Day' FROM View_DailyPlanning "
+ " where (OrderDate='" + DateTime.Now.ToShortDateString() + "' and SupplyDays='" + day + "')", DataAccessBase.GetSqlConnection());
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable("View_DailyPlanning");
da.Fill(dt);
grid_display.AutoGenerateColumns = true;
grid_display.ItemsSource = dt.DefaultView;
grid_display.Columns[0].Width = 100;
grid_display.Columns[1].Width = 150;
grid_display.Columns[2].Width = 100;
grid_display.Columns[3].Width = 100;
grid_display.Columns[4].Width = 100;
grid_display.Columns[5].Width = 100;
grid_display.Columns[6].Width = 100;
grid_display.Items.Add(new Item() { CName = "Someone4", CLocation = "xxx",VehicleNo="1234",Quantity="26",Date="10/07/2014",SupplyDays="Friday"});
How to add additional rows to grid-view,any ideas for do this.,
So from scratch, you can add new rows with the following code
DataTable dt = new DataTable();
if (dt.Columns.Count == 0)
{
dt.Columns.Add("ColumnA", typeof(string));
dt.Columns.Add("ColumnB", typeof(string));
}
DataRow NewRow = dt.NewRow();
NewRow[0] = "Some Text";
NewRow[1] = "Some Other Text";
dt.Rows.Add(NewRow);
GridView1.DataSource = dt;
GridViewl.DataBind();
To add additional rows use
DataRow NewRow = dt.NewRow();
I hope this helps

Using for loop to delete data in database

I want to delete every item in the array from the database.
string[] ids = dt.AsEnumerable()
.Select(row => row["ProductID"].ToString())
.ToArray();
for (int i = 0; i <= ids.Length; i++) {
string val = ids[i];
MySqlCommand cmd1 = new MySqlCommand();
cmd1.CommandText = "Delete from tblindividualproduct where ProductID = #p1";
cmd1.Parameters.AddWithValue("#p1", val);
}
When I run this the line
string val = ids[i];
gives me an error which says:
Index was outside the bounds of the array.
What's wrong with this?
This is my whole code UPDATED
string connString = "Server=192.168.1.100;Database=product;Uid=newuser;Pwd=password";
MySqlConnection conn = new MySqlConnection(connString);
string[] ids = dt.AsEnumerable()
.Select(row => row["ProductID"].ToString())
.ToArray();
try
{
MySqlCommand cmd1 = new MySqlCommand();
conn.Open();
cmd1.CommandText = "Delete from tblindividualproduct where ProductID = #p1";
cmd1.Parameters.AddWithValue("#p1", "");
for (int i = 0; i < ids.Length; i++)
{
string val = ids[i];
cmd1.Parameters[0].Value = val;
cmd1.ExecuteNonQuery();
}
MessageBox.Show("Checkout Successful");
}
Arrays in .NET are zero based and thus the valid indexes go from zero to length - 1.
You should change your code to
for (int i = 0; i < ids.Length; i++)
As pointed by other answer you loop also fails to call cmd1.ExecuteNonQuery and it seems that you don't have associated a connection to the MySqlCommand (thus it will not work at all).
An interesting variation on your code could be to create a single string with all of your commands and submit the command just one time.
Beware that this is not recommended unless you are absolutely sure that your ID are just numbers and not coming from user input
StringBuilder sb = new StringBuilder();
for (int i = 0; i <= ids.Length; i++)
sb.AppendFormat("Delete from tblindividualproduct where ProductID = {0};", ids[i]);
MySqlCommand cmd1 = new MySqlCommand();
cmd1.CommandText = sb.ToString();
cmd1.Connection = connection;
cmd1.ExecuteNonQuery();
Array indexes go from 0 up to Length - 1, so you need to stop the loop before i == ids.Length. Try replacing the <= with <. Also, don't forget to call ExecuteNonQuery to execute your command.
for (int i = 0; i < ids.Length; i++) {
string val = ids[i];
MySqlCommand cmd1 = new MySqlCommand(conn);
cmd1.CommandText = "Delete from tblindividualproduct where ProductID = #p1";
cmd1.Connection = conn;
cmd1.Parameters.AddWithValue("#p1", val);
cmd1.ExecuteNonQuery();
}
You can also set up the command outside of the loop and only set the parameter and execute the command inside the loop:
MySqlCommand cmd1 = new MySqlCommand(conn);
cmd1.CommandText = "Delete from tblindividualproduct where ProductID = #p1";
cmd1.Connection = conn;
cmd1.Parameters.AddWithValue("#p1", "");
for (int i = 0; i < ids.Length; i++) {
string val = ids[i];
cmd1.Parameters[0].Value = val;
cmd1.ExecuteNonQuery();
}
This will be much more efficient as there's only one call to the DB, plus there's no need anymore to iterate through yours ids collection.
string[] ids = dt.AsEnumerable()
.Select(row => row["ProductID"].ToString())
.ToArray();
MySqlCommand cmd1 = new MySqlCommand();
cmd1.CommandText = "Delete from tblindividualproduct where ProductID IN (" + String.Join(",", ids) + ")";
Your index goes from 0 to your length -1 like this:
tring[] ids = dt.AsEnumerable()
.Select(row => row["ProductID"].ToString())
.ToArray();
for (int i = 0; i < ids.Length; i++) {
string val = ids[i];
MySqlCommand cmd1 = new MySqlCommand();
cmd1.CommandText = "Delete from tblindividualproduct where ProductID = #p1";
cmd1.Parameters.AddWithValue("#p1", val);
}
And Index was outside the bounds of the array. means that your accessed an element that does not exist with that index.

Categories