I am trying to select specific persons with their ID by using ASP.NET Gridview, but only the last userID reads. Let's say I have ID's 3, 4, and 6, and only ID number 6 does not appear in the Gridview table but 3 and 4 appear. They
should not appear even 3 and 4 because I am running the sql script as:
WHERE NOT EmployeeId = " + userID.
foreach (int userID in userIDList)
{
string cs = ConfigurationManager.ConnectionStrings["MYDB"].ConnectionString;
using (SqlConnection con = new SqlConnection(cs))
{
SqlCommand cmd = new SqlCommand("SELECT FirstName, LastName FROM Employee WHERE NOT EmployeeId = " + userID, con);
con.Open();
GridView4.DataSource = cmd.ExecuteReader();
GridView4.DataBind();
}
}
Your query is inside the loop. At each loop you execute the query and bind the grid with the result of the query REPLACING the previous result.
Of course you end up with the last result only.
But you don't need any kind of loop, just use the IN clause that allows you to specify a list of values to filter your results.
Change your code to
string cs = ConfigurationManager.ConnectionStrings["MYDB"].ConnectionString;
using (SqlConnection con = new SqlConnection(cs))
{
string inClause = string.Join(",", userIDList);
SqlCommand cmd = new SqlCommand(#"SELECT FirstName, LastName
FROM Employee WHERE EmployeeId NOT IN(" + inClause + ")", con);
con.Open();
GridView4.DataSource = cmd.ExecuteReader();
GridView4.DataBind();
}
EDIT
It seems that you have some kind of unexplicable error in the string.Join call. Not clear what is causing it because, as far as I know, you should be able to pass a List<int> as second parameter to string.Join. However, you could force your List of integers to become an array of strings with this code
string inClause = string.Join(",", userIDList
.Select(x => x.ToString())
.ToArray()
Related
I want to pass a column2 to a function and update column3 with output of function. I have made func function to calculae the output. When i run the program
it only takes last value as input and outputs all columns with same value.What am i doing wrong?
sqlite1 = new SQLiteConnection("DataSource = D:/datab.db;version=3");
sqlite1.Open();
string query1 = "select * from ramrotable";
SQLiteCommand cmd = new SQLiteCommand(query1, sqlite1);
SQLiteDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
Console.WriteLine("Age::" + reader["age"]);
//int data = Convert.ToInt16(reader["age"]);
string tempquery = string.Format("UPDATE ramrotable SET num =
func({0})",reader["age"]);
cmd = new SQLiteCommand(tempquery, sqlite1);
cmd.ExecuteNonQuery();
}
string query4 = "select * from ramrotable";
cmd = new SQLiteCommand(query4, sqlite1);
reader = cmd.ExecuteReader();
while (reader.Read())
{
Console.WriteLine("Name: " + reader["name"] + " Age: " +
reader["age"] + " Num: " + reader["num"]);
}
You need to use a WHERE clause to tell SQLite which record to update exactly. Otherwise all records will be affected. Please make sure that in the WHERE clause you use a column (or a combination of columns) the identify the record uniquely!
Ideally, every record will have an ID column that contains a unique value and is the Primary Key.
I understand from the comments to the question that you actually want to update the value of the num column depending on a value from the age column of the same record, for all the records in the table.
To do this, you neither need to fetch all the records nor do you need to loop. All you need to do is invoke the following statement:
UPDATE ramrotable SET num = func(age)
This takes the value of the age column, passes it to func and sets the result as the new value for the num column for each record in the table.
So all of what you've written above can be shortened to
sqlite1 = new SQLiteConnection("DataSource = D:/datab.db;version=3");
sqlite1.Open();
cmd = new SQLiteCommand("UPDATE ramrotable SET num = func(age)", sqlite1);
cmd.ExecuteNonQuery();
When using
string tempquery = string.Format("UPDATE ramrotable SET num =
func({0})",reader["age"]);
you are updating each row with current func(age) value.
For updating each row with exact value you should use single command outside of the while loop:
string updatequery = "UPDATE ramrotable SET num = func(age)";
cmd = new SQLiteCommand(updatequery, sqlite1);
cmd.ExecuteNonQuery();
I am working on my windows form applications. In this winform, I have a checkListBox which binded the data from my sql db. I am trying to match the checkListBox's checkedItem to my sql table column's text which is stored as a nvarchar data type. I ran the debug mode and found out that it skip the entire while loop when the program is executed. I have no idea why because the valuable name items did actually showed which checkbox in checkListBox is checked
This is my code.
foreach(var items in checkListBox1.CheckedItems){
string query = "select * from my_table WHERE employeeName = '"+items+"'"
SqlCommand myCommand = new SqlCommand(query, myConn);
SqlDataReader dr = myCommand.ExecuteReader();
while(dr.Read()){
//read the column
}
}
Here is the screen Shot. I tried to fetch the chineseName in the column (don't worry about what it is lol)
You have multiple problems in your code. You don't need to write your query in ForEach loop. And if you are expecting to get multiple values from your checklistbox then equalto = operator is not your friend, you would need to use IN operator. Now check below example.
private void button1_Click(object sender, EventArgs e)
{
string items = string.Empty;
foreach (var item in checkedListBox1.CheckedItems)
{
if (items.Length == 0)
items = item.ToString();
else
items = items + "," + item;
}
//make myCommand object and open connection on your own
myCommand = new SqlCommand(query, myConn);
string query = #'select distinct firstName, lastName, chineseName, teacherEmail, entryYear, leaveYear, userLoginId, ad.applicationId
from [teacher_detail] as td
LEFT JOIN[class_detail] as cd ON td.teacherId = cd.teacherId
LEFT JOIN[application_teacher] as at ON at.teacherId = td.teacherId
LEFT JOIN[application_detail] as ad ON at.applicationId = ad.applicationId
Where ad.applicationId = 2
and chineseName in (#name)'
myCommand.Parameters.Add("#name", SqlDbType.nvarchar);
myCommand.Parameters["#name"].Value = items;
//now execute query
}
As Data type in database is nvarchar try it by modifying the following statement in your code
string query = "select * from my_table WHERE employeeName = '"+items+"'"
to
string query = "select * from my_table WHERE employeeName = N'"+items.ToString()+"'"
Prefix 'N' is used for the value to compare from checked item
I'm using this code to select the maxID from a database table and each time I want to add a new record, the autogenerated ID is not the last one +1.
public formularAddCompanie()
{
InitializeComponent();
try
{
string cs = "Data Source=CODRINMA\\CODRINMA;Initial Catalog=TrafficManager;Integrated Security=True";
string select = "SELECT max(IDCompanie) FROM Companii";
using (SqlConnection con = new SqlConnection(cs))
{
con.Open();
SqlCommand cmd2 = new SqlCommand(select, con);
SqlDataReader sda = cmd2.ExecuteReader();
DataTable idmax = new DataTable("idmax");
idmax.Load(sda);
if (idmax.Rows[0][0].ToString().Trim() == "") { txtID.Text = "1"; }
else { txtID.Text = (int.Parse(idmax.Rows[0][0] .ToString() + 1).ToString()); }
}
}
catch (Exception er) { MessageBox.Show(er.Message); }
}
The table from where the selection is made, looks like this:
IDCompany Name Address City RegNo
1 A Street NY 123
Each time I want to add a new record, the autogenerated ID is like this: 11, 111, 1111. It takes the last ID and add another 1 next to it. What am I missing?
Interestingly, note that
string a = "The meaning of life is " + 42;
converts 42 to a string, creating the result
a == "The meaning of life is 42"
Look at this code:
(int.Parse(idmax.Rows[0][0] .ToString() + 1).ToString()); }
You are converting idmax.Rows[0][0] to a string and adding +1 to the end of the string rather than to an integer value. Try
(int.Parse(idmax.Rows[0][0].ToString()) + 1).ToString(); }
Note that idmax.Rows[0][0] should already have an integer in it (as pointed out in the comments). If that's the case, you can simplify to
(idmax.Rows[0][0] + 1).ToString(); }
idmax.Rows[0][0].ToString() + 1 produces string, not int.
You can try
txtID.Text = (Convert.ToInt32(idmax.Rows[0][0]) + 1).ToString();
I just add this because it seems that none cares about the weakness of the code posted by the poster.
First the MAX function is not reliable if you want to find the next autoincrement value that will be assigned to an ID column. Concurrency could wreak havoc with any schema that use MAX. Just suppose that another user has already retrieved the MAX for its own INSERT operation, then depending on the relative speed of the two computers you or the other user will insert a duplicate value for the IDCompany field.
The only correct way to do this common task is to use the IDENTITY property for the column IDCompany and when you need to insert a new record you should write something like this
try
{
string insert = "INSERT INTO Companii (Name,Address,City,RegNo)
VALUES(#name,#address,#city,#regno);
SELECT SCOPE_IDENTITY()";
using (SqlConnection con = new SqlConnection(cs))
using (SqlCommand cmd = new SqlCommand(insert, con))
{
con.Open();
cmd.Parameters.Add("#name", SqlDbType.NVarChar).Value = txtBoxCity.Text;
.... and on for the other parameters ....
int companyID = Convert.ToInt32(cmd.ExecuteScalar());
... work with the just added company if required
}
}
catch (Exception er)
{ MessageBox.Show(er.Message); }
SCOPE_IDENTITY will return the last identity value inserted into an identity column in the same scope and in this context scope means the connection used by your command.
In any case, if the MAX approach is still required then the code could be simplified a lot using a modified query and SqlCommand.ExecuteScalar instead of building an SqlDataReader, filling a datatable, trying to parse the result with ifs
string getMax = #"select COALESCE(MAX(IDCompany), 0) + 1 AS maxPlusOne
from Companii"
using(SqlConnection cnn = new SqlConnection(.....))
using(SqlCommand cmd = new SqlCommand(getMax, cnn))
{
cnn.Open();
int nextCompanyID = Convert.ToInt32(cmd.ExecuteScalar());
}
The COALESCE function checks the result of the MAX function and if it is NULL returns the second parameter (here 0), then just increment by 1 to get the next MAX directly from the database. ExecuteScalar will do the call returning just the maxPlusOne alias field
try this snippet:
Convert Your String into Int. String with + operator will con-cat and with int it will add numbers.
if (idmax.Rows[0][0].ToString().Trim() == "") { txtID.Text = "1"; }
else {
txtID.Text = Convert.ToString(Convert.ToInt32(idmax.Rows[0][0] .ToString())+1); }
Try This one, my id format is USR001.The code will generate auto id based on the last id inside the database. If the last id in the database is USR001, the the code will generate USR002 and put the id to the textbox
con.Open();
string sqlQuery = "SELECT TOP 1 kode_user from USERADM order by kode_user desc";
SqlCommand cmd = new SqlCommand(sqlQuery, con);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
string input = dr["kode_user"].ToString();
string angka = input.Substring(input.Length - Math.Min(3, input.Length));
int number = Convert.ToInt32(angka);
number += 1;
string str = number.ToString("D3");
txtKodeUser.Text = "USR" + str;
}
con.Close();
in the following code , Im trying to assign reader(r33) into array so i can use the values of this array in the next sql command. can you help me doing this ?
//connection
SqlConnection c = new SqlConnection("Data Source=localhost\\sqlexpress;Initial Catalog=BookStoreDataBase1;Integrated Security=True;Pooling=False;");
c.Open();
//first statment
string raf = string.Format("Select Id from [Order] WHERE customerID={0}", k);
SqlCommand comm1 = new SqlCommand(raf, c);
SqlDataReader r33 = comm1.ExecuteReader();
r33.Read();
int [] k2 = r3.GetInt32(0);
r33.Close();
//second statment
string raf4 = string.Format("Select * from orderDetails WHERE orderId={0}", k2);
SqlCommand comm14 = new SqlCommand(raf4, c);
SqlDataReader r333 = comm14.ExecuteReader();
not very sure what you asked, but as far as I understood, you first query will return multiple rows containing different IDs and you want to use them in second command. Basic way of doing it would be :
string IDs = "(";
while (r33.read())
{
IDs += r33.GetString(0) + ",";
}
IDs += ")"
IDs = IDs.Replace(",)",")");
and then use IN keyword for multiple IDs you got
string raf4 = string.Format("Select * from orderDetails WHERE orderId IN {0}", IDs);
I have the following code:
SqlConnection c = new SqlConnection("Data Source=localhost\\sqlexpress;Initial Catalog=BookStoreDataBase1;Integrated Security=True;Pooling=False;");
c.Open();
string raf = string.Format("Select Id from Customer WHERE email='{0}'", DropDownList1.SelectedItem.Text);
SqlCommand comm2 = new SqlCommand(raf, c);
SqlDataReader r = comm2.ExecuteReader();
The object r now has the value of the query which is a row contains that the Id where email equals to random value from drop down list.
what I want is to get the exact value of that "Id" and assign it to label. please help me.
First of all your query is open to SQL Injection attack so change it like this:-
string raf = "Select Id from Customer WHERE email= #Email";
SqlCommand comm2 = new SqlCommand(raf, c);
cmoo2.Parameters.Add("#Email",SqlDbType.NVarchar,20).Value =
DropDownList1.SelectedItem.Text;
You are fetching just one value so it can be done use ExecuteScalar like this:-
labelid.Text= cmoo2.ExecuteScalar.ToString();
But If you want to use SqlDataReader object then it will return the value when you call the Read method:-
using(SqlDataReader reader= cmoo2.ExecuteReader())
{
while (reader.Read())
{
labelid.Text= reader["Id"].ToString();
}
}
There are lot of examples already in stack overflow regarding this topic you can refer any of that answers or try this
using(SqlDataReader r= cmd.ExecuteReader())
{
while (r.Read())
{
var myString = r.GetString(0); //The 0 stands for "the 0'th column", so the first column of the result.
labelid.Text=myString;
}
}