I am trying to update my data in a SQL Server database through C#. I am getting updated. But the problem is the data is updated twice.
For example I have 10 (int) in my balance and if I add another 10, it turns to 30.
Any help would be appreciated.
Here is my code:
protected void LoginClick(object sender, EventArgs e)
{
DataTable dr = new DataTable();
string email = txtEmail.Text;
SqlConnection con = new SqlConnection(Ws.Con);
con.Open();
int s = Convert.ToInt32(add.Text);
SqlCommand cmd = new SqlCommand("Update [Order] set Balance=Balance+'" + s + "',Card='" + card.Text + "' where email=#email ", con);
cmd.Parameters.AddWithValue("email", email);
SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
sda.Fill(dt);
int i = cmd.ExecuteNonQuery();
con.Close();
}
I would like to rectify few mistakes in your code,
DataTable is not needed to execute the update query, ExecuteNonQuery will do the job
The adapter.Fill and ExecuteNonQuery do the same job here and that's why your updates happening twice
Make use of parameterization while dealing with user inputs to avoid exceptions
For parsing integers use int.TryParse instead for Convert.ToInt32
I think the following code would help you to do the same function in a smarter way:
int currentBalance = 0;
if(int.TryParse(txtAdd.Text, out currentBalance))
{
string querSql = "Update [Order] set Balance = Balance + #balance," +
" Card = #card where email = #email"
using (SqlConnection dbConn = new SqlConnection("connectionString here"))
{
dbConn.Open();
using (SqlCommand sqlCommand = new SqlCommand(querySql, dbConn))
{
sqlCommand.Parameters.Add("#balance", SqlDbType.int).value = currentBalance;
sqlCommand.Parameters.Add("#card", SqlDbType.VarChar).value = card.Text;
sqlCommand.Parameters.Add("#email", SqlDbType.VarChar).value = email;
sqlCommand.ExecuteNonQuery();
}
}
}
Please note: YOu are parsing the balance as an integer value, so I assume the column Balance is an integer field in the database, if not make use of corresponding datatype for the parameter #balance also update the parsing technique
As per the documentation:
SqlDataAdapter(SqlCommand)
Initializes a new instance of the SqlDataAdapter class with the specified SqlCommand as the SelectCommand property.
What is going wrong in your code?
Actually you are passing SqlDataAdapter your update query as the Select command. So now when you will use this instance of SqlDataAdapter to Fill your datatable then actually you are executing your Update command. Look at the following code along with comments to see what is going wrong:
DataTable dr = new DataTable();
string email = txtEmail.Text;
SqlConnection con = new SqlConnection(Ws.Con);
con.Open();
int s = Convert.ToInt32(add.Text);
SqlCommand cmd = new SqlCommand("Update [Order] set Balance=Balance+'" + s + "',Card='" + card.Text + "' where email=#email ", con);
cmd.Parameters.AddWithValue("email", email);
SqlDataAdapter sda = new SqlDataAdapter(cmd);//The Select command for SqlDataAdapter
//is actually now the update command specified by cmd instnace of SqlCommand
DataTable dt = new DataTable();
sda.Fill(dt);//here SqlDataAdapter will execute it's Select command which is actually set
//to an update statement so your record will be updated
int i = cmd.ExecuteNonQuery();//and here again the update command is being executed now
//directly using the SqlCommand cmd instance and thus your record gets updated twice
con.Close();
Fixed Code:
DataTable dr = new DataTable();
string email = txtEmail.Text;
SqlConnection con = new SqlConnection(Ws.Con);
con.Open();
int s = Convert.ToInt32(add.Text);
SqlCommand cmd = new SqlCommand("Update [Order] set Balance=Balance+'" + s + "',Card='" + card.Text + "' where email=#email ", con);
cmd.Parameters.AddWithValue("email", email);
//Create a new SqlComamnd
SqlCommand selectCommand = new SqlCommand("Select * from [Order]");
//Put the newly created instance as SelectCommand for your SqlDataAdapter
SqlDataAdapter sda = new SqlDataAdapter(selectCommand);
DataTable dt = new DataTable();
sda.Fill(dt);
int i = cmd.ExecuteNonQuery();
con.Close();
Hope this help and do have a look at the documentation for better understanding of the SqlDataAdapter and DataTable. Thanks.
Related
I'm writing a SQL command to insert new record into a SQL Server database using an ASP.NET website, but it's not working, although it's preserving the id of an auto-increment column.
When the auto-increment value is 5, and then I try to insert a new row using Management Studio, it does insert the record with id=7.
Thanks to anyone who tells me what I'm doing wrong here
Here is the code:
SqlConnection con = new SqlConnection();
con.ConnectionString = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
DataTable dt = new DataTable();
SqlDataAdapter sda = new SqlDataAdapter();
try
{
cmd.CommandText = "insert into Bill values (#car, #date, #client, #speedometer, #employee, #notes)";
cmd.Parameters.AddWithValue("#car", carid);
cmd.Parameters.AddWithValue("#date", txt_bill_date.Value);
cmd.Parameters.AddWithValue("#client", cmb_client_name.Value);
cmd.Parameters.AddWithValue("#speedometer", txt_car_gas.Value);
cmd.Parameters.AddWithValue("#employee", cmb_emp.Value);
cmd.Parameters.AddWithValue("#notes", txt_notes.Value);
cmd.ExecuteNonQuery();
cmd.CommandText = "select top 1 bill_id from Bill order by bill_id DESC";
DataTable inserted = new DataTable();
sda.Fill(inserted);
if (inserted.Rows.Count > 0)
{
billid = inserted.Rows[0]["bill_id"].ToString();
contractid.Values["id"] = inserted.Rows[0]["bill_id"].ToString();
Response.Redirect("BillContracts.aspx");
}
}
catch(Exception ex)
{
ClientScript.RegisterClientScriptBlock(this.GetType(), "alert", "swal('خطأ', '" + ex.Message + "', 'error')", true);
}
Sorry for the inconvenience guys
your advice of putting a break point on the catch saved my day
the problem was with the columns type
apparently be mistake i added an int column for a string value
i apologize again if i didn't do this right
I have below data in SQL query, and am showing the current user "Domain" logged in I want to show the full name in label based on each user using the Windows form,
I got stuck here, how I can continue to find the value
string userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
label1.Text = userName.ToUpper();
SqlConnection con = new SqlConnection("Data Source=127.0.0.1;Initial Catalog=db;User ID=AAA;password=******");
con.Open();
string command7 = "SELECT distinct [fullname] ,[Group] ,[Domain] FROM [tableA] where fullname is not null and [group] is not null and [Domian] = '"+ label1.Text + "'";
SqlCommand da7 = new SqlCommand(command7, con);
Full name
Group
Domain
Alex Sam J
A GROUP
test\Alex
Jon Pete F
B GROUP
test\Jon
You can get the value of full name this way :
...
SqlCommand cmd = new SqlCommand(command7, con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
labelFullName.Text = da.Tables[0].Rows[0]["fullname"].ToString();
I solve it like this, thanks
SqlCommand cmd = new SqlCommand(da7, con);
cmd.CommandType = CommandType.Text;
//con.Open();
SqlDataReader reader = cmd.ExecuteReader();
//DataTable dt7 = new DataTable();
while (reader.Read())
{
label21.Text = reader["Technician"].ToString();
}
con.Close();
string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
SqlConnection con = new SqlConnection(constr);
con.Open();
string selstatus = "select status from Status where c_email=#c_email";
SqlCommand cmd = new SqlCommand(selstatus, con);
cmd.Parameters.AddWithValue("#c_email", Session["user"].ToString());
SqlDataAdapter sda = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
DataTable dt = new DataTable();
string value = Session["user"].ToString();
DataRow[] row =dt.Select(value);
sda.Fill(ds);
sda.Fill(dt);
if(row!=null){
Label13.Text = ds.Tables[0].Rows[0]["status"].ToString();
}else{
Label13.Text = "No response from mechanic";
}
cmd.ExecuteNonQuery();
con.Close();
I have been finding way to check a specific email id exist in the table. But I can't query what is the correct format to do so. I just need that if a specific email id is available then a message should be displayed.
There is no need for the DataAdapter, DataTable etc. Simply count the number of records
select count(1) from Status where c_email=#c_email
and then on the SqlCommand just use ExecuteScalar:
string selstatus = "select count(1) from Status where c_email=#c_email";
SqlCommand cmd = new SqlCommand(selstatus, con);
cmd.Parameters.AddWithValue("#c_email", Session["user"].ToString());
var count = cmd.ExecuteScalar();
// if count=0 the email doesnt exist
I am new to ASP.NET C#, I am working to develop web forms to send and receive messages (SQL Server as database) like emails. I want to store the result of SQL query in Session Variable and use it later in another page.
Kindly help me how can I do that, please correct if any things goes wrong.
Here is my code:
SqlConnection con = new SqlConnection("Data Source=AZEEM\\SQLEXPRESS; Initial Catalog=kics;User ID=sa;Password=123");
con.Open();
String query = "select username as sender,subject,message from emailtable where receiver='" + Session["username"] + "'";
enter code here
//this is the query for which I want to store the result in variable myvar, how can I store the result of following query in variable myvar and use it later, when I execute it, string is shown instead of result of string.
String myvar = "select receiver from emailtable where username='" + Session["username"] + "'";
SqlDataReader reader = null;
SqlCommand cmd = new SqlCommand(query, con);
SqlCommand cmd2 = new SqlCommand(myvar, con);
DataTable dt = new DataTable();
SqlDataAdapter sda = new SqlDataAdapter(cmd);
sda.Fill(dt);
reader = cmd2.ExecuteReader();
GridView1.DataSource = dt;
GridView1.DataBind();
DataSet ds = new DataSet();
ds = myvar;
Try below,
SqlConnection con = new SqlConnection("Data Source=AZEEM\\SQLEXPRESS; Initial Catalog=kics;User ID=sa;Password=123");
con.Open();
String query = "select username as sender,subject,message from emailtable where receiver='" + Session["username"] + "'";
enter code here
//this is the query for which I want to store the result in variable myvar, how can I store the result of following query in variable myvar and use it later, when I execute it, string is shown instead of result of string.
String myvar = "select receiver from emailtable where username='" + Session["username"] + "'";
SqlDataReader reader = null;
SqlCommand cmd = new SqlCommand(query, con);
SqlCommand cmd2 = new SqlCommand(myvar, con);
DataTable dt = new DataTable();
SqlDataAdapter sda = new SqlDataAdapter(cmd);
sda.Fill(dt);
reader = cmd2.ExecuteReader();
GridView1.DataSource = dt;
GridView1.DataBind();
session["dt"] = dt;
When you retrieve,
if (session["dt"] != null) {
DataTable dt = (DataTable)session["dt"];
}
You Need to Pass that Query to this Method which will return you the result Set and then try to assign it to the Session
String myvar = "select receiver from emailtable where username='" + Session["username"] + "'";
Session["myvar"] = GetData(myvar);
Method for GetData as Follows
private static DataTable GetData(string query)
{
DataTable dt = new DataTable();
string constr = "Data Source=AZEEM\\SQLEXPRESS; Initial Catalog=kics;User ID=sa;Password=123";
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand(query))
{
using (SqlDataAdapter sda = new SqlDataAdapter())
{
cmd.CommandType = CommandType.Text;
cmd.Connection = con;
sda.SelectCommand = cmd;
sda.Fill(dt);
}
}
return dt;
}
}
I knew this is simple but I am not able to think. Displaying the count of a record from table and display it on textbox.
private void gMapControl1_Load_1(object sender, EventArgs e)
{
SqlConnection conDatabase = new SqlConnection(constring);
conDatabase.Open();
DataTable db = new DataTable();
SqlDataAdapter sda = new SqlDataAdapter(
"select count(site) from [ICPS].[dbo].[excel GPS postcode]",
conDatabase);
sda.Fill(db);
textBox29.Text = ;
SqlDataAdapter sda = new SqlDataAdapter(
"select count(site) from [ICPS].[dbo].[excel GPS postcode] "
+ "where Region = '1'",
conDatabase);
sda.Fill(db);
textBox30.Text = ;
}
You just need to use SqlCommand.ExecuteScalar instead of SqlDataAdapter like this:
SqlCommand com = new SqlCommand("select count(site) from [ICPS].[dbo].[excel GPS postcode]", conDatabase);
object count = com.ExecuteScalar();
if(count != null) textBox29.Text = count.ToString();
//The same for textBox30
More info on ExecuteScalar
Note that the code I posted is just for the idea of using ExecuteScalar, it depends on your code style when working with ADO.NET, you may want to use some using statement, or reuse your command, ... in your own way you like.
using (SqlConnection conn = new SqlConnection(connString))
{
conn.Open();
cmd.CommandText = "select count(site) from [ICPS].[dbo].[excel GPS postcode]";
Int32 count = (Int32) cmd.ExecuteScalar();
textBox29.Text = count.ToString();
}
When you expect just one value returned by your sql command, then use ExecuteScalar from the command object
string cmdText1 = "select count(site) from [ICPS].[dbo].[excel GPS postcode]";
using(SqlConnection conDatabase = new SqlConnection(constring))
using(SqlCommand cmd = new SqlCommand(cmdText, conDatabase))
{
conDatabase.Open();
int numRec = Convert.ToInt32(cmd.ExecuteScalar());
textBox29.Text = numRec.ToString();
}
MSDN says
Executes the query, and returns the first column of the first row in
the result set returned by the query. Additional columns or rows are
ignored
However I have noticed that you try to read the record count from two different queries.
So your code could also be written in this way to avoid a roundtrip to the database
string cmdText = "select count(site) from [ICPS].[dbo].[excel GPS postcode];" +
"select count(site) from [ICPS].[dbo].[excel GPS postcode] " +
"where Region = '1'", ;
using(SqlConnection conDatabase = new SqlConnection(constring))
using(SqlCommand cmd = new SqlCommand(cmdText, conDatabase))
{
conDatabase.Open();
using(SqlDataReader reader = cmd.ExecuteReader())
{
reader.Read();
int numRec1 = Convert.ToInt32(reader[0]);
reader.NextResult();
reader.Read();
int numRec2 = Convert.ToInt32(reader[0]);
textBox29.Text = numRec1.ToString();
textBox30.Text = numRec2.ToString();
}
}
In this way I have taken advantage of the ability of SQL Server to execute two or more commands separated by a semicolon.
To fetch a value from datatable use row[columnName]
SqlDataAdapter sda = new SqlDataAdapter(
"select count(site) As siteCount from [ICPS].[dbo].[excel GPS postcode]",
conDatabase);
sda.Fill(db);
if(db !=null && db.Rows.Count > 0)
textBox29.Text =db["siteCount"].tostring();
else
textBox29.Text ="0";
However as King King suggested here why use datatable if you have to fetch just a single row and single column use ExecuteScalar method .
Executes the query, and returns the first column of the first row in the result set returned by the query. Additional columns or rows are ignored. -MSDN
SqlCommand com = new SqlCommand("select count(site) from [ICPS].[dbo].[excel GPS postcode]", conDatabase);
object siteCount = com.ExecuteScalar();
if(siteCount != null) textBox29.Text = siteCount.ToString();