for (int i = 0; i <= GridView1.Rows.Count - 1; i++)
{
string toemail = GridView1.Rows[i].Cells[2].Text;
string FID1 = GridView1.Rows[i].Cells[0].Text;
GridViewRow row = GridView1.Rows[i];
CheckBox Ckbox = (CheckBox)row.FindControl("CheckBoxMark1");
if (Ckbox.Checked == true)
{
sendMail(toemail);
//ClientScript.RegisterStartupScript(Page.GetType(), "validation", "<script language='javascript'>alert('Email send Succesfully')</script>");
ClientScript.RegisterStartupScript(Page.GetType(), "validation", "<script language='javascript'>alert('Email sent Succesfully on " + test + "')</script>");
cn1.Open();
//cmd4.CommandText = "Insert into TrackingFaculty_det (EmailsentDate) values (#EmailsentDate) WHERE FID=#FID";
cmd4.CommandText = "update TrackingFaculty_det SET EmailsentDate=#Email WHERE FID=#FID ";
cmd4.CommandType = CommandType.Text;
cmd4.Connection = cn1;
cmd4.Parameters.Add("#Email", SqlDbType.DateTime, 8);
cmd4.Parameters["#Email"].Value = sdt;
cmd4.Parameters.Add("#FID",SqlDbType.VarChar,10);
cmd4.Parameters["#FID"].Value = FID1;
cmd4.ExecuteNonQuery();
cn1.Close();
}
}
//This is a part of c# code along with asp.net
The problem arises if whenever the for loop gets executed the updation should be done in the database but when for loop executes more than once the update query will give a error as The variable name '#Email' has already been declared. Variable names must be unique within a query batch or stored procedure..Any solution for this?
Just move the invariant part of your loop outside the loop. That means, the initialization of the SqlCommand, the opening of the connection and the creation of the parameters collection.
Then inside the loop just change the value of the parameters and execute. (This will be always faster than recreating the same list of parameters inside the loop)
SqlCommand cmd4 = new SqlCommand("update TrackingFaculty_det " +
"SET EmailsentDate=#Email WHERE FID=#FID", cn1);
cn1.Open();
cmd4.Parameters.Add("#Email", SqlDbType.DateTime, 8);
cmd4.Parameters.Add("#FID",SqlDbType.VarChar,10);
for (int i = 0; i <= GridView1.Rows.Count - 1; i++)
{
.....
if (Ckbox.Checked == true)
{
....
cmd4.Parameters["#Email"].Value = sdt;
cmd4.Parameters["#FID"].Value = FID1;
cmd4.ExecuteNonQuery();
}
}
cn1.Close();
Try clearing command parameters -
cmd4.Parameters.Clear();
and then add the parameter
cmd4.Parameters.Add("#Email", SqlDbType.DateTime, 8);
So your final code would be-
cmd4.Parameters.Clear(); // <- Just add this line
cmd4.Parameters.Add("#Email", SqlDbType.DateTime, 8);
cmd4 object should be refreshed everytime.
cmd4.Parameters.Add("#Email", SqlDbType.DateTime, 8);
cmd4.Parameters["#Email"].Value = sdt;
cmd4.Parameters.Add("#FID",SqlDbType.VarChar,10);
cmd4.Parameters["#FID"].Value = FID1;
your adding the same parameters more than one time to parameter list of "cmd4"
Clear your paramters before adding once again same parameters
cmd4.Parameters.Clear();
check the Run Stored Procedure with table data as parameter
or second is create string with below example and exec(string) in sql server
sqlstr= "update TrackingFaculty_det SET EmailsentDate=2#2.com WHERE FID=1; update TrackingFaculty_det SET EmailsentDate=1#1.com WHERE FID=#FID ;pdate TrackingFaculty_det SET EmailsentDate=2#2.com WHERE FID=1;"
Related
I have a table with some columns like
now I want to use a for loop to set
out_0 = 0,
out_1 = 1,
out_2 = 2,
out_3 = 3,
out_4 = 4
so I update it with such code as
string sql = "update exchange_out set #column = #id where member_id = 6;";
SqlCommand cmd = new SqlCommand(sql, connet);
cmd.Parameters.Add("#column", SqlDbType.NVarChar);
cmd.Parameters.Add("#id", SqlDbType.Int);
int n = 0;
for (int i = 0; i < 5; i++)
{
cmd.Parameters["#column"].Value = "out_" + i;
cmd.Parameters["#gid"].Value = i;
n = cmd.ExecuteNonQuery();
MessageBox.Show("" + n);
}
but it didn't write any data into the table while it literally did five times of updating, because the messagebox returns "1" five times.
finally I solve this by
for (int i = 0; i < 5; i++){
sql = string.Format("update exchange_out set {0} = {1} where member_id = 6", "out_" + i, i);
}
but I'm still wondering why it didn't work by adding parameters?
any respond will be appreciated. :)
I'm still wondering why it didn't work by adding parameters?
Identifiers such as table and column names cannot be parameterized in this way, only data. Your attempt effectively runs a query like this:
update exchange_out set 'out_1' = 1 where member_id = 6;
It's the same in any programming language:
var data1 = "hello";
var whichData = "1";
Console.WriteLine(data+whichData); //it doesn't compile; you cannot programmatically build a variable name `data1` in this way
The way you found is reasonably the only way but you should still parameterize the data:
using var cmd = new SqlCommand(sql, connet);
cmd.Parameters.Add("#data", SqlDbType.NVarChar);
cmd.Parameters.Add("#id", SqlDbType.Int);
for (int i = 0; i < 5; i++){
sql = string.Format("update exchange_out set out_{0} = #data where member_id = #id", i);
cmd.CommandText = sql;
cmd.Parameters["#data"].Value = ...
cmd.Parameters["#id].Value = 6;
...
You could also start with an SQL stub like "UPDATE t SET " and repeatedly concatenate on identifiers and parameters:
using var cmd = new SqlCommand(sql, connet);
cmd.Parameters.Add("#data", SqlDbType.NVarChar);
cmd.Parameters.Add("#id", SqlDbType.Int);
var sql = "UPDATE exchange_out SET ";
for (int i = 0; i < 5; i++){
sql += string.Format("out_{0} = #data{0},", i);
cmd.Parameters["#data"+i].Value = ...
}
sql = sql.TrimEnd(',');
sql += " where member_id = #id";
cmd.Parameters["#id"].Value = 6;
cmd.CommandText = sql;
...
This does the update in one operation, running a query like UPDATE t SET out_1 = #data1, out_2 = #data2 ...
These are safe from SQL injection because your code controls the entire SQL; there isn't any capacity for a user to provide '; DROP TABLE Students;-- as the {0} going into the identifier in this case but take care that you don't arrange for it to be possible (don't let the user provide identifier text)..
Your non-parameter attempt is also safe from SQL injection in this case by virtue of inserting intergers that you control, rather than strings you don't, but be careful you don't universally apply the technique and one day include user-suppied strings. If you do find yourself in that suitable you should use something like a whitelist of user input - any string identifier provided by the user that isn't whitelisted should not be put in the SQL
I need to change my field QB_STATUS from value R to value C. I am doing this in a loop because i cannot "requery" the table as data may have changed.
I have built a list of entries to update. The code does not error and iterates through 5 times (correct based on my idInvoices list) but the field does not get updated.
for (int i = 0; i < idInvoices.Count; i++)
{
// following command will update one row as ID_Invoice is primary key.
// ID_Invoice taken from list previously built in ReadDataToNAVArray
SqlCommand cmd = new SqlCommand("UPDATE tblINVOICES SET QB_STATUS=#Status WHERE ID_INVOICE = #IDInvoice", myConnection);
cmd.Parameters.Add("#Status", "C");
cmd.Parameters.Add("#IDInvoice", idInvoices[i]);
cmd.Dispose();
}
First, you have to execute your query: ExecuteNonQuery; second - do not create command, parameters etc within the loop, just assign values and execute:
// Make SQL readable
String sql =
#"UPDATE tblINVOICES
SET QB_STATUS = #Status
WHERE ID_INVOICE = #IDInvoice";
// wrap IDisposable into "using"
// do not recreate command in the loop - create it once
using (SqlCommand cmd = new SqlCommand(sql, myConnection)) {
cmd.Parameters.Add("#Status", SqlDbType.VarChar); //TODO: check types, please
cmd.Parameters.Add("#IDInvoice", SqlDbType.Decimal); //TODO: check types, please
// Assign parameters with their values and execute
for (int i = 0; i < idInvoices.Count; i++) {
cmd.Parameters["#Status"].Value = "C";
cmd.Parameters["#IDInvoice"].Value = idInvoices[i];
cmd.ExecuteNonQuery();
}
}
You are missing the ExecuteNonQuery in your command.
for (int i = 0; i < idInvoices.Count; i++)
{
SqlCommand cmd = new SqlCommand("UPDATE tblINVOICES SET QB_STATUS=#Status WHERE ID_INVOICE = #IDInvoice", myConnection);
cmd.Parameters.Add("#Status", "C");
cmd.Parameters.Add("#IDInvoice", idInvoices[i]);
cmd.ExecuteNonQuery();
cmd.Dispose();
}
I think you're missing cmd.ExecuteNonQuery();.
An example for a different way of using sql commands:
SqlConnection addConn = new SqlConnection();
addConn.ConnectionString = Properties.Settings.Default.yourDataBaseConnection;
addConn.Open();
SqlCommand addComm = new SqlCommand();
addComm.Connection = addConn;
addComm.CommandText = "sql command";
addComm.ExecuteNonQuery();
I am trying to update a column in the database, from a list
command = new SqlCommand("update Login_Users set Password=#a where UserName !='" + null + "'", Db);
Db.Open();
for (int i = 0; i < list.Count; i++)
{
list[i] = Encrypt(list[i]);
command.Parameters.AddWithValue("#a",list[i]);
int a = command.ExecuteNonQuery();
}
but I get this error:
variable name already been declared
Your command only has one parameter, but you are attempting to add a new one through each loop (via AddWithValue ... add with value).
Either put the command declaration in the loop (as below), or use one of the other methods to update the value.
Db.Open();
for (int i = 0; i < list.Count; i++)
{
command = new SqlCommand("update Login_Users set Password=#a where UserName !='" + null + "'", Db);
list[i] = Encrypt(list[i]);
command.Parameters.AddWithValue("#a",list[i]);
int a = command.ExecuteNonQuery();
}
In query you have one parameter called #a - check if your list has only one item. If not that's problem. Meybe it will be better to remove for loop and assign all parameters manually.
Why in query you do something like this:
where UserName !='" + null + "'"
I think much more readable is like this:
where UserName !=''
or
where UserName <>''
You have setup your SqlCommand with a SQL statement that includes a parameter #a. With that set, you can call the command multiple times via the ExecuteQuery after setting the parameter #a to different values.
Within your for loop, the statement command.Parameters.AddWithValue() is potentially adding to the command additional parameter, but no two parameters can have the same value so if your loop is executed more than once, you'll get the error you received.
Your SQL statement appears to be setting the password of all records in Login_Users to some encrypted value multiple times based on your list. If I understand correctly, maybe this would do what you want:
var command = new SqlCommand("update Login_Users set Password=#a where UserName !='" + null + "'", Db);
Db.Open();
command.Parameters.Add(new SqlParameter("#a",null));
for (int i = 0; i < list.Count; i++)
{
cmd.Parameters["#a"].Value = Encrypt(list[i]);
int a = command.ExecuteNonQuery();
}
Good luck!
I've been searching for a while but the answers I find usually involve stored procedures or different functionality.
I am trying to execute a reader and also return a scalar in the one query. I thought I could do this using an output parameter, but I get an exception to check my syntax near NULL = #rows_found(), so it appears the output parameter is not getting initialized.
Basically I need to know if this is possible as I haven't found a code sample like this that works.
command.CommandText = #"
SELECT SQL_CALC_FOUND_ROWS
accounting.*
FROM
accounting
WHERE
transaction_type = #transaction_type
LIMIT
#index, #results;
SET #total_rows = FOUND_ROWS();
";
command.Parameters.AddWithValue("transaction_type", transaction_type);
command.Parameters.AddWithValue("index", index);
command.Parameters.AddWithValue("results", results);
MySqlParameter totalRows = new MySqlParameter("total_rows", 0);
totalRows.Direction = System.Data.ParameterDirection.Output;
command.Parameters.Add(totalRows);
using (MySqlDataReader dr = command.ExecuteReader())
{
while (dr.Read())
invoices.Add(new AccountingDataModel(dr));
}
invoices.Total = (int)totalRows.Value;
cmd.Parameters["#output"].Value.ToString()
Use command object to access your out parameter ....
you can not access out perameter directly.
You Should use like
invoices.Total = Convert.ToInt32(command.Parameters["total_rows"].Value.ToString())
example for stored procedure
MySqlCommand cmd = new MySqlCommand(nameOfStoredRoutine, connection);
cmd.CommandType = CommandType.StoredProcedure;
//input parameters
for (int i = 0; i < (parameterValue.Length / 2); i++)
{
cmd.Parameters.AddWithValue(parameterValue[i, 0], parameterValue[i, 1]);
cmd.Parameters[parameterValue[i, 0]].Direction = ParameterDirection.Input;
parameterList = parameterList + parameterValue[i,0] + " " + parameterValue[i,1] + " ";
}
//single output parameter
cmd.Parameters.AddWithValue("#output", MySqlDbType.Int32);
cmd.Parameters["#output"].Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery(); //Execute command
return Convert.ToInt32(cmd.Parameters["#output"].Value.ToString());
It seems that this is not possible. From the documentation of MySqlParameter's members for the Direction property:
Gets or sets a value indicating whether the parameter is input-only, output-only, bidirectional, or a stored procedure return value parameter. As of MySQL version 4.1 and earlier, input-only is the only valid choice.
So the parameter is, no matter what you set Direction to, always an input parameter. If you change the value from null to anything else (e.g. 15) you should see that the generated query is something like
SET 15 = FOUND_ROWS()
Eventually i ended up running two queries. Probably this is not as performant as it could be, but at least it gets the desired result (using EF Core):
using (var context = new MyDbContext(...))
{
context.Database.OpenConnection();
var estates = context.MySet
.FromSql("SELECT SQL_CALC_FOUND_ROWS * FROM myset LIMIT 25 OFFSET 25")
.ToList();
var cmd = context.Database.GetDbConnection().CreateCommand();
cmd.CommandText = "SELECT FOUND_ROWS()";
var rows = (long)cmd.ExecuteScalar();
context.Database.CloseConnection();
}
this is what i am trying to do after receiving string from the serial port. i get whitespace between the data so i put two loops to eliminate them. i want to recieve data spanning multiple columns and a single row for every single run of do while loop.. Thanks in Advance
string text = sp.readline();
for (int i = 0; i < text.Length; )
{
p = text[i].ToString();
if (p != " ")
{
do
{
x += text[i].ToString();
s = text[i].ToString();
i++;
} while (s != " ");
try
{
string col = "column" + no.ToString();
MySqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "INSERT INTO testdata("+col+")VALUES(?data)";
cmd.Parameters.Add("?data", MySqlDbType.VarChar).Value = x;
cmd.ExecuteNonQuery();
x = "";
p = "";
no++;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
} i++;
}
Sorry to say, you cannot, in any dialect of SQL, provide a table or column name as a bindable variable (or parameter). If it's working for MySQL that's terrific, but if you change over to any other DBMS make and model, it will suddenly stop working.
Also, INSERT means create a new row. You'll either need to insert all the column values at once in a single INSERT statement, or figure out how to INSERT one row and then UPDATE it for each new column value.
if you want to insert a single row having multiple column, then for loop is not required
following is for three columns
int no = 2;
cmd.CommandText = "INSERT INTO testdata(?col1,?col2,?col3)VALUES(?data1,?data2,?data3)";
cmd.Parameters.Add("?col1", MySqlDbType.String).Value = col1;
cmd.Parameters.Add("?col2", MySqlDbType.String).Value = col2;
cmd.Parameters.Add("?col3", MySqlDbType.String).Value = col3;
cmd.Parameters.Add("?data1", MySqlDbType.VarChar).Value = x1;
cmd.Parameters.Add("?data2", MySqlDbType.VarChar).Value = x2;
cmd.Parameters.Add("?data3", MySqlDbType.VarChar).Value = x3;
cmd.ExecuteNonQuery();