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);
Related
i am creating a simple inventory system using c#. sales product table data added success.but sales table data added twice i don't know why. what i tried so far i attached below. i attached the sales table below record added twice
sales table
id subtoal pay bal
27 900.00 1000.00 100.00
28 900.00 1000.00 100.00
string bal = txtBal.Text;
string sub = txtSub.Text;
string pay = textBox1.Text;
sql = "insert into sales(subtoal,pay,bal) values(#subtoal,#pay,#bal); select ##identity;";
con.Open();
cmd = new SqlCommand(sql, con);
cmd.Parameters.AddWithValue("#subtoal", sub);
cmd.Parameters.AddWithValue("#pay", pay);
cmd.Parameters.AddWithValue("#bal", bal);
int lastinsertID = int.Parse(cmd.ExecuteScalar().ToString());
cmd.ExecuteNonQuery();
string proddname;
int price;
int qty;
int tot;
for (int row = 0; row < dataGridView1.Rows.Count; row++)
{
proddname = dataGridView1.Rows[row].Cells[0].Value.ToString();
price = int.Parse(dataGridView1.Rows[row].Cells[1].Value.ToString());
qty = int.Parse(dataGridView1.Rows[row].Cells[2].Value.ToString());
int total = int.Parse(dataGridView1.Rows[row].Cells[3].Value.ToString());
sql1 = "insert into sales_product(sales_id,prodname,price,qty,total) values(#sales_id,#prodname,#price,#qty,#total)";
cmd1 = new SqlCommand(sql1, con);
cmd1.Parameters.AddWithValue("#sales_id", lastinsertID);
cmd1.Parameters.AddWithValue("#prodname", proddname);
cmd1.Parameters.AddWithValue("#price", price);
cmd1.Parameters.AddWithValue("#qty", qty);
cmd1.Parameters.AddWithValue("#total", total);
cmd1.ExecuteNonQuery();
}
MessageBox.Show("Record Addddedddd");
con.Close();
As per Larnu's commment you were executing the query twice. In this case you should only use the ExecuteScalar() version to retrieve the last inserted id for later use
I also wanted to point out that the design intent is to initialize the parameters collection once, then re use it many times, executing each time. You should also put using statements to make your commands, more like this, and you should probably get into the habit of using SCOPE_IDENTITY() rather than ##identity:
using(var con = new SqlConnection(...)){
con.Open();
string bal = txtBal.Text;
string sub = txtSub.Text;
string pay = textBox1.Text;
sql = "insert into sales(subtoal,pay,bal) values(#subtoal,#pay,#bal); select scope_identity();";
int lastinsertId = 0;
using(var cmd = new SqlCommand(sql, con){
cmd.Parameters.AddWithValue("#subtoal", sub);
cmd.Parameters.AddWithValue("#pay", pay);
cmd.Parameters.AddWithValue("#bal", bal);
lastinsertID = (int)cmd.ExecuteScalar();
}
string proddname = "";
int price = 0;
int qty = 0;
int tot = 0;
sql1 = "insert into sales_product(sales_id,prodname,price,qty,total) values(#sales_id,#prodname,#price,#qty,#total)";
using(var cmd1 = new SqlCommand(sql1, con)){
cmd1.Parameters.AddWithValue("#sales_id", lastinsertID);
cmd1.Parameters.AddWithValue("#prodname", proddname);
cmd1.Parameters.AddWithValue("#price", price);
cmd1.Parameters.AddWithValue("#qty", qty);
cmd1.Parameters.AddWithValue("#total", total);
for (int row = 0; row < dataGridView1.Rows.Count; row++)
{
proddname = dataGridView1.Rows[row].Cells[0].Value.ToString();
price = int.Parse(dataGridView1.Rows[row].Cells[1].Value.ToString());
qty = int.Parse(dataGridView1.Rows[row].Cells[2].Value.ToString());
int total = int.Parse(dataGridView1.Rows[row].Cells[3].Value.ToString());
cmd1 = new SqlCommand(sql1, con);
cmd1.Parameters["#sales_id"].Value = lastinsertID;
cmd1.Parameters["#prodname"].Value = proddname;
cmd1.Parameters["#price"].Value = price;
cmd1.Parameters["#qty"].Value = qty;
cmd1.Parameters["#total"].Value = total;
cmd1.ExecuteNonQuery();
}
} //end using sqlcommand
}//end using sqlconnection - it will close as a result
MessageBox.Show("Record Addddedddd");
And then I also wanted to point out that your life could get a lot easier if you use Dapper. With dapper the code would look more like:
using(var connection = new SqlConnection(...))
sql = "insert into sales(subtoal,pay,bal) values(#subtoal,#pay,#bal); select scope_identity();";
var lastInsertId = connection.Query<int>(sql, new {
subtoal = txtSub.Text,
pay = textBox1.Text,
bal = txtBal.Text
}
).Single();
foreach(...)
}
It does all the parameter jiggling for you, runs the query, manages the connection ,returns a type casted int etc
Also if your datagridview is based on a DataTable (and even better a strongly typed datatable) you can use it in your foreach. Here's what a strongly typed table would look like:
using(...){
foreach(var ro in SalesProductTable){
sql = "insert into sales_product(sales_id,prodname,price,qty,total) values(#sales_id,#prodname,#price,#qty,#total)";
dapperConnection.Execute(sql, new { ro.sales_id, ro.prodname, ro.price, ro.qty, ro.total });
}
Yep, that's it; just 4 lines of code, and it's easier if your #param names match your column names in your strongly typed table.
I think you might even just be able to get Dapper to do the looping too, by passing the datatable in, so long as the rows have properties that are the same as the parameters in the query:
using(...){
sql = "insert into sales_product(sales_id,prodname,price,qty,total) values(#sales_id,#prodname,#price,#qty,#total)";
dapperConnection.Execute(sql, salesProductTable);
}
take a look - http://dapper-tutorial.net
I am making payroll management system in which double pay salary is equal to some proportion of employee's fix pay.That proportion is given by some percentage i.e. 12% of fix pay and this percentage tends to change time by time. And when the percentage is changed then double pay value according to that percentage must also be changed in employee table.
here is my code:
string query;
query = "select count(*) from ConditionalEarnings where [Double Duty]!=0";
SqlCommand value = new SqlCommand(query,DataFind);
value.ExecuteNonQuery();
int no = Convert.ToInt32(value.ExecuteScalar());
textBox7.Text = no.ToString();
for (int o = 0; o< no; o++)
{
string query1;
query1 = "select EmpId from ConditionalEarnings where [Double Duty]!=0";
SqlCommand value1 = new SqlCommand(query1, DataFind);
value1.ExecuteNonQuery();
int id = Convert.ToInt32(value1.ExecuteScalar());
textBox8.Text = id.ToString();
string query2;
query2 = "Select EmpRunningBasic from EmployeeRunningBasic where EmpId=#id";
SqlCommand r = new SqlCommand(query2,DataFind);
r.Parameters.Add("#id", SqlDbType.VarChar).Value = id;
r.ExecuteNonQuery();
int rb = Convert.ToInt32(r.ExecuteScalar());
int doublechange = Convert.ToInt32(textBox1.Text);
int apply = (rb * doublechange)/100;
SqlCommand f = new SqlCommand("Update ConditionalEarnings set [Double Duty]='" + apply + "' where EmpId=#id", DataFind);
f.Parameters.Add("#id", SqlDbType.VarChar).Value = id;
f.ExecuteNonQuery();
}
And my form is as follow:
Its my form
This is my code to perform task.
When I enter percentage and execute program to update all values in that specific column of double pay, only 1st row of table is changed and all other row's cell for double duty remain unchanged. Means my program works in a loop and calculate and replace value of my first row's column again and again without going to the next row. How to apply change on all rows selected on base of same criteria?
its my table showing employee id column and double duty column highlighted
The value of double duty column is not changing for all employee ids but for only first id in table.
First you have to get the Employees (with their Running Basics) that you want to Iterate, then apply your calculation on every one then update your database
have a look at the below code , it may help you (modify the code to match your needs)
int no = 0;
string query = "select count(*) from ConditionalEarnings where [Double Duty]!=0";
using (SqlConnection conn = new SqlConnection(connString))
{
SqlCommand cmd = new SqlCommand(query, conn);
conn.Open();
no = Convert.ToInt32(cmd.ExecuteScalar());
}
string selectQuery = "select a.EmpId,b.EmpRunningBasic from ConditionalEarnings a left join EmployeeRunningBasic b on a.EmpId=b.EmpId where a.[Double Duty]!=0";
SqlDataAdapter adapter = new SqlDataAdapter(selectQuery, DataFind);
DataTable dtEmp;
adapter.Fill(dtEmp);
textBox7.Text = no.ToString();
string updateQuery = "";
foreach (DataRow row in dtEmp)
{
string empId = row["EmpId"].ToString();
textBox8.Text = empId;
int rb = Convert.ToInt32(row["EmpRunningBasic"]);
int doublechange = Convert.ToInt32(textBox1.Text);
int apply = (rb * doublechange) / 100;
updateQuery += string.Format("Update ConditionalEarnings set [Double Duty]='{1}' where EmpId='{0}';", empId, apply);
}
if (!string.IsNullOrEmpty(updateQuery))
{
using (SqlConnection conn = new SqlConnection(connString))
{
SqlCommand cmd = new SqlCommand(updateQuery, conn);
conn.Open();
cmd.ExecuteNonQuery();
}
}
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()
I need select the maximum ID of PolygonId column. I save my data like this
string sql = "create table Polygons (PolygonId int, PointId int, X double, Y double)";
// Выполнение нашей команды
using (SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection))
{
command.ExecuteNonQuery();
}
int pointId = 1;
for (int i = 0; i < listOfCustomPolygons.Count; i++)
for (int j = 0; j < listOfCustomPolygons[i].listOfVertexes.Count; j++)
{
string strSQL =
string.Format("INSERT INTO Polygons (PolygonId,PointId,X,Y) Values ('{0}','{1}','{2}','{3}')",
i+1,pointId,listOfCustomPolygons[i].listOfVertexes[j].X,
listOfCustomPolygons[i].listOfVertexes[j].Y );
pointId++;
using (SQLiteCommand insertCommand = new SQLiteCommand(strSQL, m_dbConnection))
{
insertCommand.ExecuteNonQuery();
}
}
After this I want select the max value from table Polygons and column PolygonId, but I got an IndexOutOfRangeException. How a can solve this problem?
using (SQLiteConnection connection = new SQLiteConnection("Data Source=" + openFileDialog.FileName + ";Version=3;"))
{
connection.Open();
string selectMaxId = "Select Max(PolygonId) From Polygons";
string selectQuery = "Select * From Polygons";
SQLiteCommand selectMaxCmd = new SQLiteCommand(selectMaxId,connection);
SQLiteDataReader dataReader = selectMaxCmd.ExecuteReader();
int maxId = Convert.ToInt32(dataReader["Select Max(PolygonId) From Polygons"]); // This is don't work! Why?
I found out the solution! It should look like
string selectMaxId = "Select Max(PolygonId) From Polygons";
SQLiteCommand selectMaxCmd = new SQLiteCommand(selectMaxId,connection);
object val = selectMaxCmd.ExecuteScalar();
int maxId = int.Parse(val.ToString());
I hope it can help somebody who face with similar problem)
First of all don't create table every time you run your code :) But you probably know that
You type like this:
int maxId = Convert.ToInt32(dataReader["Select Max(PolygonId) From Polygons"]);
Try this:
string selectMaxId = "Select Max(PolygonId) From Polygons";
SQLiteCommand selectMaxCmd = new SQLiteCommand(selectMaxId,connection);
SQLiteDataReader dataReader = selectMaxCmd.ExecuteReader();
int maxID = -1;
while(dataReader.read())
{
maxID = (int)dataReader.GetValue(0);
}
//This Works for me in WPF C#:
int MaxNum=0;
sqliteCon.Open();
string Query = "SELECT MAX(Promo_No)FROM Promo_File";
SQLiteCommand createCommand = new SQLiteCommand(Query, sqliteCon);
SQLiteDataReader DR = createCommand.ExecuteReader();
while (DR.Read())
{
MaxNum = DR.GetInt16(0);
}
sqliteCon.Close();
I had the same problem!
You have to learn the difference method of SQLiteCommand.
1.SQLiteCommand.ExecuteReader(). Get a SqlDataReader.
2.SQLiteCommand.ExecuteScalar(). Get a single value from the database.
Microsoft Doc:
cmd.CommandText = "SELECT COUNT(*) FROM dbo.region";
Int32 count = (Int32) cmd.ExecuteScalar();
My table structure is as follows:
Session
--------------
SessionID (PK)
RoomID
SessionDate
SessionTimeStart
SessionTimeEnd
I have a following query which will always return one row and display in DGV. I use DataAdapter for connection:
DataTable queryResult = new DataTable();
string ConnStr = "Data Source=DUZY;Initial Catalog=AutoRegSQL;Integrated Security=True";
SqlConnection MyConn = new SqlConnection(ConnStr);
MyConn.Open();
//SQL query that returns todays sessions for the given roomID
string query = #"SELECT SessionID, RoomID, SessionDate, SessionTimeStart, SessionTimeEnd" +
" FROM [Session] " +
" WHERE RoomID = #RoomID " +
" AND SessionDate = cast(getdate() as date) ";
SqlCommand command = new SqlCommand(query, MyConn);
command.Parameters.Add("RoomID", SqlDbType.Char).Value = RoomID;
SqlDataAdapter adapter = new SqlDataAdapter(command);
adapter.Fill(queryResult);
I would like to save the query result into multiple strings representing table columns, i.e.
SessionIDstring = query result for SessionID column
RoomIDstring = query result for RoomID column
and so on...
Is it possible to achieve it using one query, or do I have to create 5 queries for each column?
Something similar to this, perhaps, using ADO.NET?
//SQL query that returns todays sessions for the given roomID
string query = #"SELECT SessionID, RoomID, SessionDate, SessionTimeStart, SessionTimeEnd" +
" FROM [Session] " +
" WHERE RoomID = #RoomID " +
" AND SessionDate = cast(getdate() as date) ";
using (var connection = new SqlConnection(ConnStr))
using (var command = new SqlCommand(query, connection))
{
command.Parameters.Add("RoomID", SqlDbType.Char).Value = RoomID;
try
{
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
if (reader.Read())
{
// Note that reader[x] has the equivalent type to the type
// of the returned column, converted using
// http://msdn.microsoft.com/en-us/library/cc716729.aspx
// .ToString() if the item isn't null is always ok
string SessionIDstring = reader[0].ToString(); // it should be an int
// reading it twice is ok
int RoomID = (int)reader[1]; // it should be an int
string RoomIDstring = reader[1].ToString(); // it should be an int
if (reader.Read())
{
throw new Exception("Too many rows");
}
}
else
{
throw new Exception("No rows");
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
This code was adapted from MSDN ADO.NET Code Examples. I added some usings and made it single row. I don't even want to know why MSDN examples don't go the full length with using.
Note that SqlDataAdapter are built to recover multiple rows/big data and put them in a DataSet. You can use them for single row data, but it's much easier to simply use a SqlDataReader if you only want to fill some variables.
declare #col1 int
declare #col2 varchar(42)
select #col1 = col1
, #col2 = col2
, ....
You could create a class like so...
public class SessionDto
{
public string SessionID {get; set;}
public string RoomID {get; set;}
public string SessionDate {get; set;}
public string SessionTimeStart {get; set;}
public string SessionTimeEnd {get; set;}
}
And then have a method that takes a Room ID and builds your session object
public SessionDto GetSessionData(int roomId)
{
using (var cnn = new SqlConnection(ConnStr))
{
SessionDto sessionDto;
string query = #"SELECT SessionID, RoomID, SessionDate, SessionTimeStart, SessionTimeEnd" +
" FROM [Session] " +
" WHERE RoomID = #RoomID " +
" AND SessionDate = cast(getdate() as date) ";
cnn.Open();
using (var cmd = new SqlCommand(query,cnn))
{
cmd.Parameters.Add("#RoomID", SqlDbType.Char).Value = roomId;
using (var rdr = cmd.ExecuteReader())
{
if (rdr.HasRows)
{
while (rdr.Read())
{
sessionDto = new sessionDto{
SessionID = rdr.GetString(0),
RoomID = rdr.GetString(1),
SessionDate = rdr.GetString(2),
SessionTimeStart = rdr.GetString(3),
SessionTimeEnd = rdr.GetString(4)
};
}
}
}
}
}
return sessionDto;
}
A lot of this is hand typed as I havent got access to VS right now,
but you should get it to work.
Also, I have used rdr.GetString(), there are other methods for GetType().