How to exclude unchanged columns sql table c# - c#

How do I exclude some columns from being modified using SQL Update statement? Here is the code, but I want to update only the columns that user enter data in. Using Windows Forms in C#.
EXAMPLE, I want to update only the Class using the Windows Form
var query="update UserRegistration Set FirstName= #FirstName, LastName=#LastName, Class=#Class, [Password]=#Password WHERE UserID=#UserID";
cmd.Parameters.AddWithValue("#UserID", SqlDbType.VarChar).Value = txtuserid.Text;
cmd.Parameters.AddWithValue("#FirstName", SqlDbType.VarChar).Value = txtfirstname.Text;
cmd.Parameters.AddWithValue("#LastName", SqlDbType.VarChar).Value = txtlastname.Text;
cmd.Parameters.AddWithValue("#Class", SqlDbType.VarChar).Value = txtclass.Text;

You can use ISNULL function. Or an analog in other RDBMS.
Change SQL query like this
update UserRegistration set
FirstName = isnull(#FirstName, FirstName),
LastName = isnull(#LastName, LastName),
Class = isnull(#Class, Class),
[Password] = isnull(#Password, [Password])
where UserID = #UserID;
Also change C# code like this
cmd.Parameters.Add("#FirstName", SqlDbType.VarChar).Value =
txtfirstname.Text == "" ? null : txtfirstname.Text;

Dynamically create a SQL command using only the the field names that are populated. (This is a brute force method, and could be simplified by using a dictionary, but shown like this to make it simpler to understand)
var fieldList = new List<string>();
cmd.Parameters.AddWithValue("#UserID", SqlDbType.VarChar).Value = txtuserid.Text;
if(!string.IsNullOrEmpty(txtfirstname.Text))
{
fieldList.Add("FirstName=#FirstName");
cmd.Parameters.AddWithValue("#FirstName", SqlDbType.VarChar).Value = txtfirstname.Text;
}
if(!string.IsNullOrEmpty(txtlastname.Text))
{
fieldList.Add("LastName=#LastName");
cmd.Parameters.AddWithValue("#LastName", SqlDbType.VarChar).Value = txtlastname.Text;
}
if(!string.IsNullOrEmpty(txtclass.Text))
{
fieldList.Add("Class=#Class");
cmd.Parameters.AddWithValue("#Class", SqlDbType.VarChar).Value = txtclass.Text;
}
var fields = string.Join(',', fieldNames);
var query=$"update UserRegistration SET {fields} WHERE UserId=#UserID";
This means that if you only want to update the first name, the query string becomes:
update UserRegistration SET FirstName=#FirstName WHERE UserId=#UserId

Related

System.Data.SqlClient.SqlException: 'Conversion failed when converting the nvarchar value to data type int.'

I have creates a database and I am trying to INSERT INTO TABLE with the following code:
string sqlquery = "INSERT INTO Runner VALUES (#firstName, #lastName, #amount, #category, #city, #charity, #route)";
cmd = new SqlCommand(sqlquery, conn);
conn.Open();
cmd.Parameters.AddWithValue("#firstName", txtFirstName.Text.ToString());
cmd.Parameters.AddWithValue("#lastName", txtLastName.Text.ToString());
cmd.Parameters.AddWithValue("#amount", Convert.ToInt32(txtMoney.Text));
cmd.Parameters.AddWithValue("#category", cbBoxCategory.ValueMember);
cmd.Parameters.AddWithValue("#city", cbBoxCity.ValueMember);
cmd.Parameters.AddWithValue("#charity", cbBoxCharity.ValueMember);
cmd.Parameters.AddWithValue("#route", cbBoxRoute.ValueMember);
cmd.ExecuteNonQuery();
conn.Close();
When I run it, I get this error:
System.Data.SqlClient.SqlException: 'Conversion failed when converting the nvarchar value 'id' to data type int.'
All my cbBox (comboBox) need to leave a INT, I understand that is need to convert to NVARCHAR to INT, I try to use Convert.Into32(cbBox.Category.ValueMember) but without success.
I have tried everything with no success.
After looking for other people answer I find this solution.
string sqlquery = "INSERT INTO Runner (firstName, lastName, amount, categoryID, cityID, charityID, routeID) VALUES (#firstName, #lastName, #amount, #category, #city, #charity, #route)";
cmd = new SqlCommand(sqlquery, conn);
conn.Open();
cmd.Parameters.Add("#firstName", SqlDbType.VarChar, 50).Value = txtFirstName.Text;
cmd.Parameters.Add("#lastName", SqlDbType.VarChar, 50).Value = txtLastName.Text;
cmd.Parameters.Add("#amount", SqlDbType.Int).Value = txtMoney.Text;
cmd.Parameters.Add("#category", SqlDbType.Int).Value = cbBoxCategory.SelectedValue;
cmd.Parameters.Add("#city", SqlDbType.Int).Value = cbBoxCity.SelectedValue;
cmd.Parameters.Add("#charity", SqlDbType.Int).Value = cbBoxCharity.SelectedValue;
cmd.Parameters.Add("#route", SqlDbType.Int).Value = cbBoxRoute.SelectedValue;
cmd.ExecuteNonQuery();
MessageBox.Show("New Runner has been registered!");
conn.Close();
By using Convert.ToInt32(cbBoxRoute.SelectedValue)
Here is the link where I find my solution:
Insert ID into SQL from C# Combo box

How to use insert and update command using c#

I have GridView and I am trying to check Task_ID from a table, if it is found then I want to update the record but if Task_ID is not found in the table then I want to insert it into my table. My code now does the insert part but it does not do the update part of the code. I was wondering how you can do this within the same code. Please help. thanks
here is my code:
int index = 0;
foreach (GridViewRow row in myGV.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
Label ID = row.FindControl("lbl_ID") as Label;
string UID = Request.Form[row.FindControl("hfUId").UniqueID];
DateTime strDate = DateTime.Now;
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["myCon"].ConnectionString);
SqlCommand cmd = new SqlCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "insert into myTable(TID, USR_ID, UPDT_DT) values(#ID, #USR_ID, #UPDT_DT) ";
cmd.Parameters.Add("#ID", SqlDbType.VarChar).Value = ID.Text;
cmd.Parameters.Add("#USR_ID", SqlDbType.VarChar).Value = UID.ToString();
cmd.Parameters.Add("#UPDT_DT", SqlDbType.VarChar).Value = strDate.Date;
cmd.Connection = con;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
con.Dispose();
cmd.Dispose();
}
index++;
}
There is a MERGE command in SQL for this purpose. Here is an example that might work for you:
Merge myTable As T
Using (Select Task_ID From myTable) As Src (Src_ID)
ON (T.Task_ID = Src.Src_ID)
WHEN MATCHED THEN
UPDATE SET T.UPDT_DT = 'your new value'
WHEN NOT MATCHED THEN
INSERT (TASK_ID, USR_ID, UPDT_DT)
VALUES (#TASK_ID, #USR_ID, #UPDT_DT);
change 'your new value' to the correct update statement
Replace the command text as below:
if not exists (select task_id from mytable where task_id = #task_id)
insert into myTable(TASK_ID, USR_ID, UPDT_DT) values(#TASK_ID, #USR_ID, #UPDT_DT)
else
update mytable set USR_ID = #USR_ID, UPDT_DT = #UPDT_DT where task_id = #TASK_ID
I would first query the database to see if the task_id existed... declare cmd, define it with a sql command like "Select count(*) from myTable where Task_ID = '" & Task_ID.text & "'" and assign that to some variable x. Then follow that with "if x <> 0 then --> define your cmd as an insert statement here, ELSE --> define cmd as "Update myTable set blah blah = values WHERE task_ID = " & task_ID.text.

c# and sql updating the dataset from a button click

Hi guys i came stuck again. I am wanting to edit a selected row from my datagridview and replace the data from dgv with the new information in the text fields. I have managed to get it to change all the data in the dataset. So what i am asking is for guidance on how to code it so it only edits the selected row.
private void btnEdit_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(constring);
SqlDataAdapter da = new SqlDataAdapter();
da.UpdateCommand = new SqlCommand(String cmdUpdate = #"update Customer set firstName = #firstName, surname = #surname, email = #email, phonenumber = #phone, mobileNumber = #mobile";
, con);
da.UpdateCommand.Parameters.Add("#firstName", SqlDbType.VarChar).Value = textFirstName.Text;
da.UpdateCommand.Parameters.Add("#surname", SqlDbType.VarChar).Value = textSurname.Text;
da.UpdateCommand.Parameters.Add("#email", SqlDbType.VarChar).Value = textEmail.Text;
da.UpdateCommand.Parameters.Add("#phone", SqlDbType.VarChar).Value = textPhone.Text;
da.UpdateCommand.Parameters.Add("#mobile", SqlDbType.VarChar).Value = textMobile.Text;
da.UpdateCommand.Parameters.Add("#ID", SqlDbType.Int).Value = customerDataSet.Customer[0].ID;
con.Open();
da.UpdateCommand.ExecuteNonQuery();
MessageBox.Show("Customer Edited");
con.Close();
}
You UPDATE query updates whole table you should use WHERE statement in this query to update the row
with current ID
update Customer
set firstName = #firstName,
surname = #surname,
email = #email,
phonenumber = #phone,
mobileNumber = #mobile
WHERE ID=#ID

Editing data into SQL with C#

I have this method for Editing data but I don't know how to write the code... Until now I have this which I don't really understand and I have an error in it. It says incorrect syntax near '('.
public void EditMember(Member member)
{
string Name = member.Name;
string Surname = member.Surname;
string EntryDate = member.EntryDate.ToString("dd.MM.yyyy");
string Status = member.Status;
sqlConnection.Open();
sqlCommand = new SqlCommand(
"UPDATE Members SET (Name, Surname, EntryDate) VALUES('" + Name + "','" + Surname + "','" + EntryDate + "')' WHERE'(' Id '='" + member.Id + "')",
sqlConnection);
sqlCommand.ExecuteNonQuery();
sqlConnection.Close();
}
The problem is when I start to write WHERE
Help please.
Please read all of this answer, not just the first part
There are multiple issues here. The most immediate problem is here:
"')' WHERE'('
That's acting as if you're trying to quote the bracket. That "should" be:
"') WHERE ('
At that point it would look like a valid (but bad) INSERT command... but your use of VALUES which doesn't look like it's a valid way of updating in T-SQL anyway.
However, you shouldn't use this approach at all. It's error-prone, hard to read, and most importantly prone to SQL injection attacks.
Instead, you should use parameterized SQL:
string sql = #"UPDATE Members
SET Name = #Name, Surname = #Surname, EntryDate = #EntryDate
WHERE Id = #Id";
using (var connection = new SqlConnection(...))
{
connection.Open();
using (var command = new SqlCommand(sql, connection))
{
command.Parameters.Add("#Name", SqlDbType.NVarChar).Value = member.Name;
command.Parameters.Add("#Surname", SqlDbType.NVarChar).Value = member.Surname;
command.Parameters.Add("#EntryDate", SqlDbType.DateTime).Value = member.EntryDate;
command.Parameters.Add("#Id", SqlDbType.NVarChar).Value = member.Id;
int rows = command.ExecuteNonQuery();
// TODO: Work out what to do if rows isn't 1
}
}
(With adjustments for the appropriate data types, of course.)
You should NEVER EVER concatenate together your SQL statements with user input.
Instead : use parametrized queries - they're easy to use, avoid SQL injection, and improve performance.
Try code something like this:
string updateStmt = "UPDATE dbo.Members SET Name = #Name, Surname = #Surname, EntryDate = #EntryDate WHERE Id = #ID";
sqlCommand = new SqlCommand(updateStmt, sqlConnection);
sqlCommand.Parameters.Add("#Name", SqlDbType.VarChar, 100).Value = name;
sqlCommand.Parameters.Add("#Surname", SqlDbType.VarChar, 100).Value = surname;
sqlCommand.Parameters.Add("#EntryDate", SqlDbType.DateTime).Value = entrydate;
sqlCommand.Parameters.Add("#ID", SqlDbType.Int).Value = member.Id;
sqlConnection.Open();
sqlCommand.ExecuteNonQuery();
sqlConnection.Close();
The correct syntax for an update statement is
"UPDATE Members SET Name = #name, Surname = #surname, EntryDate = #date WHERE id=#id"
Said that, you should use parameterized query like this
public void EditMember(Member member)
{
string Name = member.Name;
string Surname = member.Surname;
string EntryDate = member.EntryDate.ToString("dd.MM.yyyy");
string Status = member.Status;
sqlConnection.Open();
sqlCommand = new SqlCommand("UPDATE Members SET Name = #name, Surname = #surname, " +
"EntryDate = #date " +
"WHERE Id = #id", sqlConnection);
sqlCommand.Parameters.AddWithValue("#name", Name);
sqlCommand.Parameters.AddWithValue("#surname", Surname);
sqlCommand.Parameters.AddWithValue("#date", EntryDate);
sqlCommand.Parameters.AddWithValue("#id", Status);
sqlCommand.ExecuteNonQuery();
sqlConnection.Close();
As a side note, keep in mind that AddWithValue is a simple way to add parameters to you query, but if the perfomance of this query is critical it is better to use a fully defined parameter with the datatype that matches exactly your database column's type and with the exact size.
Remove the quotes from around the WHERE and you should be fine. Please heed the warnings given in the comments about SQL injection attacks.
Your code has syntax error for update and also SQLInjection issue.
You need to pass parameters to update query rather than passing direct values.
It should be as follows:
public void EditMember(Member member)
{
string Name = member.Name;
string Surname = member.Surname;
string EntryDate = member.EntryDate.ToString("dd.MM.yyyy");
string Status = member.Status;
sqlConnection.Open();
sqlCommand = new SqlCommand("UPDATE Members SET Name=#Name, Surname=#Sirname, EntryDate=#EntryDate WHERE Id = #id", sqlConnection);
sqlCommand.parameters.AddparameterWithValue("#Name",Name);
sqlCommand.parameters.AddparameterWithValue("#Surname",Surname);
sqlCommand.parameters.AddparameterWithValue("#EntryDate",EntryDate);
sqlCommand.parameters.AddparameterWithValue("#Id",Id);
sqlCommand.ExecuteNonQuery();
sqlConnection.Close();
}
Edit the post to make correct answer:
i.e. you don't need brackets in where clause. And yes the better query is
"UPDATE Members SET Name=#Name, Surname=#Surname, EntryDate=#EntryDate WHERE Id=#ID"
and then you add #Name, #Surname, .. etc through parameter of command object.

Why does SQL statement update more records than it needs to?

I have problem with my code specifically on the update code.
private void updatebtn_Click(object sender, EventArgs e)
{
String Fname = fnametb.Text;
String Lname = lnametb.Text;
String Age = agetb.Text;
String Address = addresstb.Text;
String Course = coursetb.Text;
{
connection.Open();
OleDbCommand select = new OleDbCommand();
select.Connection = connection;
select.CommandText = "Select * From Accounts";
OleDbDataReader reader = select.ExecuteReader();
while (reader.Read())
{
OleDbCommand insert = new OleDbCommand("UPDATE Accounts SET Firstname=#Fname, Lastname=#Lname, Age=#Age, Address=#Address, Course=#Course WHERE Lastname='"+ reader[2].ToString()+"'", connection);
insert.Parameters.Add("#Fname", OleDbType.VarChar).Value = Fname;
insert.Parameters.Add("#Lname", OleDbType.VarChar).Value = Lname;
insert.Parameters.Add("#Age", OleDbType.VarChar).Value = Age;
insert.Parameters.Add("#Address", OleDbType.VarChar).Value = Address;
insert.Parameters.Add("#Course", OleDbType.VarChar).Value = Course;
insert.ExecuteNonQuery();
fnametb.Clear();
lnametb.Clear();
agetb.Clear();
addresstb.Clear();
coursetb.Clear();
listBox1.Items.Clear();
searchtb.Clear();
}
connection.Close();
}
}
above is my code. Whenever I update one record, all the records in the table are affected.I think there's something wrong with the reader.
Please help, thanks.
You are selecting all records,
select.CommandText = "Select * From Accounts";
then you loop the result with the reader.
while (reader.Read())
Then you update each record.
String sql = "UPDATE Accounts SET Firstname=#Fname, Lastname=#Lname, Age=#Age, Address=#Address, Course=#Course WHERE Lastname='"+ reader[2].ToString()+"'";
OleDbCommand insert = new OleDbCommand(sql, connection);
So why are you surprised?
I'm not sure what you actually want. Maybe you have forgotten to add a WHERE clause to your first select and you want to use lnametb.Text. But then the first select is simply redundant and you could use the WHERE for the update-command:
String sql = "UPDATE Accounts SET Firstname=#Fname, Lastname=#Lname, Age=#Age, Address=#Address, Course=#Course WHERE Lastname=#LastName";
insert.Parameters.Add("#LastName", OleDbType.VarChar).Value = lnametb.Text;
Btw, why have you named your update-command insert?
The problem is that for some reason you execute the update in a loop for every record that the reader finds. Naturally, the reader would find every single last name that you have in the table, so the update is going to change every single record!
You need to remove the loop, remove the reader, and change the update command to use the last name from one of the entry boxes on the screen:
connection.Open();
OleDbCommand update = new OleDbCommand("UPDATE Accounts SET Firstname=#Fname, Age=#Age, Address=#Address, Course=#Course WHERE Lastname=#Lname", connection);
update.Parameters.Add("#Fname", OleDbType.VarChar).Value = Fname;
update.Parameters.Add("#Lname", OleDbType.VarChar).Value = Lname;
update.Parameters.Add("#Age", OleDbType.VarChar).Value = Age;
update.Parameters.Add("#Address", OleDbType.VarChar).Value = Address;
update.Parameters.Add("#Course", OleDbType.VarChar).Value = Course;
update.ExecuteNonQuery();
connection.Close();
Of course this does not let you update the last name: for that you need to supply some sort of an independent student ID, and use it in the WHERE clause of your UPDATE instead of the last name.
You are iterating all records from the table and setting to one value..
it is wrong access only the matching record and update it

Categories