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
Related
I want to know how i can take it all the tags that i have on my table and save it on a list.
string query = "SELECT JobNumber + JobName + JobTag FROM dbo.Cat05Projects WHERE JobNumber = #JobNumber AND JobTag = #JobTag";
SqlCommand command = new SqlCommand(query, cn);
command.Parameters.AddWithValue("JobNumber", JobNumber);
command.Parameters.AddWithValue("JobTag", JobTag);
SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
tags.Add(reader[0].ToString());
tags.Add(reader[1].ToString());
tags.Add(reader[2].ToString());
}
}
due to your concatenation (JobNumber + JobName + JobTag) it is not possible to use reader[X].ToString() because just a single string is going to be returned. In order to fetch records properly you have to use comma instead of plus as below.
string query = "SELECT JobNumber , JobName , JobTag FROM dbo.Cat05Projects WHERE JobNumber = #JobNumber AND JobTag = #JobTag";
You did not mention anything about tags data structure, but if i am not mistaken, after getting the correct response, if you are trying to fetch only
JobTag you can use LINQ to filter the final list.
This is what I wanted
query = "SELECT * FROM dbo.Cat05Projects WHERE JobNumber = #JobNumber AND JobTag = #JobTag";
command = new SqlCommand(query, cn);
command.Parameters.AddWithValue("JobNumber", JobNumber);
command.Parameters.AddWithValue("JobTag", JobTag);
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
for (int i = 1; i < reader.FieldCount; i++)
{
lista.Add(reader[i].ToString());
}
}
i would like to create an id generator based on their department selected from the dropdownlist. lets say my ddl has 3 departments (A,B,C) and when generating an id it will be A20181001 and then A20181002 upon submission but when i pick B from the ddl after sending A20181001 to the database, it will be B20181001.
so far i have created the code for the increment for the id without the departments. here is the code i did so far. (I used the date for today so the 20181001 is just an example):
void getMRF_No()
{
string year = DateTime.Now.Date.ToString("yyyyMMdd");
int mrf = 0;
int i;
string a;
//string x = Request.QueryString["BUnit"];
string mrfNo = "";
database db = new database();
string conn = dbe.BU();
SqlConnection connUser = new SqlConnection(conn);
SqlCommand cmd = connUser.CreateCommand();
SqlDataReader sdr = null;
string query = "SELECT TOP 1 MRF_NO FROM incMRF ORDER BY MRF_NO DESC";
connUser.Open();
cmd.CommandText = query;
sdr = cmd.ExecuteReader();
while (sdr.Read())
{
mrfNo = sdr.GetInt32(0).ToString();
}
if (mrfNo == "")
{
mrfNo = Convert.ToString(year) + "" + 00;
}
mrf += 0;
i = Convert.ToInt32(mrfNo) + 1;
a = i.ToString();
txtMRFNo.Text = a;
connUser.Close();
}
any help to improve this code will be helpful. thank you :)
EDIT:
here is the dropdown list code:
void SelectBU()
{
string database = dbe.BU ();
using (SqlConnection con = new SqlConnection(database))
{
con.Open();
string query = "select BUnit from BusinessUnit";
using (SqlDataAdapter sda = new SqlDataAdapter(query, con))
{
DataSet ds = new DataSet();
sda.Fill(ds, "BUnit");
ddlBu.DataSource = ds;
ddlBu.DataTextField = "BUnit";
ddlBu.DataValueField = "BUnit";
ddlBu.DataBind();
selectOption(ddlBu, "Select Dept");
}
con.Close();
}
}
EDIT2: I will state what im searching for here incase some doesnt know or understand. What i want is upon selecting a department from a dropdownlist, for example i picked A. the textbox show show A2018102201. if i select B it should show B2018102201 and if its C then c2018102201. and it will change its number once i submit it to a database and a new form loads. So if A2018102201 is already in the database, then the text shown in the text box will be A2018102202. BUT if i select B then the textbox will show B2018102201 since it does not exist in the database yet.
First you should get max ID, then increase the numeric part of your Id, and If this is a multi-user application, you have to lock your table, because it might create many ID duplication, Therefore I'm not recommend to create ID like this on c#, it is better to create a Sequence on SQL server. but I wrote this sample for you, just call it with proper value.
static string getMRF_No(string prefixCharFromDropDownList)
{
string year = DateTime.Now.Date.ToString("yyyyMMdd");
string mrfNo = "";
SqlConnection connUser = new SqlConnection("Server=130.185.76.162;Database=StackOverflow;UID=sa;PWD=$1#mssqlICW;connect timeout=10000");
SqlCommand cmd = new SqlCommand(
$"SELECT MAX(MRF_NO) as MaxID FROM incMRF where MRF_NO like '{prefixCharFromDropDownList}%'"
,connUser
);
connUser.Open();
SqlDataReader sdr = cmd.ExecuteReader();
while (sdr.Read())
{
mrfNo = sdr["MaxID"].ToString();
}
if (mrfNo == "")
{
mrfNo = prefixCharFromDropDownList + year + "000";
}
else
{
mrfNo = prefixCharFromDropDownList + (long.Parse(mrfNo.Substring(1)) + 1).ToString().PadLeft(2);
}
sdr.Close();
cmd = new SqlCommand($"INSERT INTO incMRF (MRF_NO) values ('{mrfNo}')",connUser);
cmd.ExecuteNonQuery();
connUser.Close();
//txtMRFNo.Text = prefixCharFromDropDownList + i.ToString();
return mrfNo;
}
I call this method on a console application as test.
static void Main(string[] args)
{
// send dropdown (selected char) as prefix to method
var newAId = getMRF_No("A");
var newAnotherAId = getMRF_No("A");
var newBId = getMRF_No("B");
var newAnotherAId2 = getMRF_No("A");
Console.ReadKey();
}
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 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();
How do I get the last id created in the policy table and store it into a variable so that I can use it for another table called backupspec table.
System.Data.SqlClient.SqlConnection dataConnection = new SqlConnection();
dataConnection.ConnectionString =
#"Data Source=JAGMIT-PC\SQLEXPRESS;Initial Catalog=SumooHAgentDB;Integrated Security=True";
System.Data.SqlClient.SqlCommand dataCommand = new SqlCommand();
dataCommand.Connection = dataConnection;
//tell the compiler and database that we're using parameters (thus the #first, #last, #nick)
dataCommand.CommandText = ("Insert Policies ( PolicyName, PolicyDesc, TimeAdded,OSFlag, CreateVSSSnapshot, CreateAuditLogForRecoveries, AllowUsersToOverwriteFiles, AutoHandleEnvErrors, NotifyOnEnvErrorCount, NotifyOnFileFailure, NotifyOnFileFailureCount, NotifyOnLackOfPCContact, NotifyOnLackOfPCContactDays, NotifyOnRecoveryFailures, NotifyOnRecoveryFailureReason) values (#pn,#pd,#TimeAdded,#os,#vss,#al,#uow,#hee,#oeec,#off,#offc,#oloc,#olocd,#orf,#orfr)");
dataCommand.Parameters.AddWithValue("#pn",pn);
dataCommand.Parameters.AddWithValue("#pd",pd);
dataCommand.Parameters.AddWithValue("#TimeAdded",TimeAdded);
dataCommand.Parameters.AddWithValue("#os",os);
dataCommand.Parameters.AddWithValue("#vss",vss);
dataCommand.Parameters.AddWithValue("#al",al);
dataCommand.Parameters.AddWithValue("#uow",uow);
dataCommand.Parameters.AddWithValue("#hee",hee);
dataCommand.Parameters.AddWithValue("#oeec",oeec);
dataCommand.Parameters.AddWithValue("#off",off);
dataCommand.Parameters.AddWithValue("#offc",offc);
dataCommand.Parameters.AddWithValue("#oloc",oloc);
dataCommand.Parameters.AddWithValue("#olocd",olocd);
dataCommand.Parameters.AddWithValue("#orf",orf);
dataCommand.Parameters.AddWithValue("#orfr",orfr);
dataConnection.Open();
dataCommand.ExecuteNonquery();
dataConnection.Close();
ArrayList jaja = (ArrayList)Session["BackupSpecList"];
for (int i = 0; i < jaja.Count; i++)
{
BackupSpecEntry bsp = (BackupSpecEntry)jaja[i];
string path = bsp.path;
string inclExcl = bsp.inclExcl;
byte inclExclFlags = bsp.inclExclFlags;
bool indexContents = bsp.indexContents;
int serverBackupSpecId = bsp.serverBackupSpecId;
int freq = bsp.freq;
int retention = bsp.retention;
int policyID =DONT KNOW HOW TO GET THIS VALUE;
long specChangeTime = 0;
long backupTime = 0;
dataCommand.CommandText = ("Insert BackupSpec (PolicyID, Path, ServerBackupSpecID, Freq, Retention, InclExclFlags, InclExcl, IndexContents, SpecChangeTime, BackupTime) values (#policyID,#path,#serverBackupSpecId,#freq,#retention,#inclExclFlags,#inclExcl,#indexContents,#specChangeTime,#backupTime)");
dataCommand.Parameters.AddWithValue("#policyID", policyID);
dataCommand.Parameters.AddWithValue("#path", path);
dataCommand.Parameters.AddWithValue("#serverBackupSpecId", serverBackupSpecId);
dataCommand.Parameters.AddWithValue("#freq", freq);
dataCommand.Parameters.AddWithValue("#retention", retention);
dataCommand.Parameters.AddWithValue("#inclExclFlags", inclExclFlags);
dataCommand.Parameters.AddWithValue("#inclExcl", inclExcl);
dataCommand.Parameters.AddWithValue("#indexContents", indexContents);
dataCommand.Parameters.AddWithValue("#specChangeTime", specChangeTime);
dataCommand.Parameters.AddWithValue("#backupTime", backupTime);
dataConnection.Open();
dataCommand.ExecuteNonQuery();
dataConnection.Close();
}
I am getting error with the label id...
can some 1 help me with this..??
I am not getting the last policyID created after inserting please help...
Please help
Use scope_identity:
strSQL = "INSERT INTO Policies (...) VALUES (#vals....);SELECT #result = scope_identity()"
SQLCommand.CommandText = strSQL;
SQLCommand.Parameters.Add("#result", SqlDbType.Int);
SQLCommand.ExecuteScalar();
int id = SQLCommand.Parameters["#result"].Value;
You can use either SCOPE_IDENTITY or ##IDENTITY
SCOPE_IDENTITY:
strSQL = "INSERT INTO Policies (...) VALUES (#vals....);SELECT SCOPE_IDENTITY()";
SQLCommand.CommandText = strSQL;
IdReturned = SQLCommand.ExecuteScalar();
##IDENTITY:
strSQL = "INSERT INTO Policies (...) VALUES (#vals....);SELECT ##Identity";
SQLCommand.CommandText = strSQL;
IdReturned = SQLCommand.ExecuteScalar();
For the differences between the two i recommend reading this article
If you do a INSERT INTO Policies() call first, in order to get the lastid, you could do something like this:
int lastId = 0;
using(SqlConnection Connection = new SqlConnection("(connection string)"))
{
string queryStatement =
"INSERT INTO dbo.Policies(fields) OUTPUT Inserted.LastID VALUES(....)";
using(SqlCommand Command = new SqlCommand(queryStatement, Connection))
{
Connection.Open();
lastId = Command.ExecuteScalar();
Connection.Close();
}
}
Use the OUTPUT ....... clause to return the newly inserted lastId.
Then go on and use that value in your main query.
Marc