Click here to Skip to main content
15,888,025 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
Hello,

I have created a Windows Form using C# Windows Application to add, update, delete and show user data from SQL.

All the queries are working perfectly but when I am updating a particular user data, the fields that I am leaving empty are becoming blank in SQL as well.

I have 3 TextBoxes:

Username
Password
Name

So if I put values in Username and Password and leave the Name field blank, then it is updating the Username and Password but making the Name field blank in the SQL.

I want the unchanged fields to remain as they were.

Please help.

What I have tried:

using (SqlConnection connection = new SqlConnection("Data Source=PRIMO-CHALICE;Initial Catalog=NewsClip;Integrated Security=SSPI"))
            {
                using (SqlCommand command = new SqlCommand())
                {
                    command.Connection = connection;            // <== lacking
                    command.CommandType = CommandType.Text;
                    command.CommandText = "UPDATE NewsClip_Login SET Username = @Username, Password = @Password, Name = @Name WHERE Username='" + this.EmployeeUsernameAdd.Text + "';";
                    command.Parameters.AddWithValue("@Username", EmployeeUsernameAdd.Text);
                    command.Parameters.AddWithValue("@Password", EmployeePasswordAdd.Text);
                    command.Parameters.AddWithValue("@Name", EmployeeNameAdd.Text);

                    try
                    {
                        connection.Open();
                        int recordsAffected = command.ExecuteNonQuery();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                    finally
                    {
                        connection.Close();
                    }
                }
Posted
Updated 10-May-18 21:50pm

Two major problems with that:
1) Never concatenate strings to build a SQL command. It leaves you wide open to accidental or deliberate SQL Injection attack which can destroy your entire database. Use Parametrized queries instead.

When you concatenate strings, you cause problems because SQL receives commands like:
SQL
SELECT * FROM MyTable WHERE StreetAddress = 'Baker's Wood'
The quote the user added terminates the string as far as SQL is concerned and you get problems. But it could be worse. If I come along and type this instead: "x';DROP TABLE MyTable;--" Then SQL receives a very different command:
SQL
SELECT * FROM MyTable WHERE StreetAddress = 'x';DROP TABLE MyTable;--'
Which SQL sees as three separate commands:
SQL
SELECT * FROM MyTable WHERE StreetAddress = 'x';
A perfectly valid SELECT
SQL
DROP TABLE MyTable;
A perfectly valid "delete the table" command
SQL
--'
And everything else is a comment.
So it does: selects any matching rows, deletes the table from the DB, and ignores anything else.

So ALWAYS use parameterized queries! Or be prepared to restore your DB from backup frequently. You do take backups regularly, don't you?

Think about what you are doing! You pass the username as a parameter, so why the heck are you tacking it on at the end and making your code vulnerable as well?

2) Never store passwords in clear text - it is a major security risk. There is some information on how to do it here: Password Storage: How to do it.[^]
To give you an idea how we feel about that kind of thing, see here: Code Crime 1[^]

Then we come to minor problems: why are you setting the username, when you know it's the same value already? Because if it was different, it wouldn't match any rows!

And finally: why is it changing the name field? Because you told it to...
If you want the name to remain untouched when it is blank, you need to check in your C# code, and either use a different query, or pass the current value instead. If you tell SQL "set it to this" then that is exactly what it will do...
 
Share this answer
 
Comments
Primo Chalice 11-May-18 5:02am    
Please tell me how to implement this in my code.

{
byte[] hashedPassword = GetSHA1(userId, password);
if (MatchSHA1(hashedPassword, GetSHA1(userId, enteredPassword)))
{
Console.WriteLine("Log him in!");
}
else
{
Console.WriteLine("Don't log him in!");
}
if (MatchSHA1(hashedPassword, GetSHA1(userId, notPassword)))
{
Console.WriteLine("Will not happen!");
}
else
{
Console.WriteLine("Don't log him in!");
}
}
OriginalGriff 11-May-18 5:14am    
Copy'n'paste?
Primo Chalice 11-May-18 5:16am    
What I meant was that I am fetching the data from SQL database. So how shall I modify the code? The original code is given in the question.
OriginalGriff 11-May-18 5:20am    
The first thing you need to do is modify your SQL database so that passwords aren't stored in plain text, but hashed - which means a VARBINARY column instead of NVARCHAR or VARCHAR.
Primo Chalice 11-May-18 5:25am    
Yes, I have done that. And I have already copied the MatchSHA1 and GetSHA1 functions.
Further to OG's response...
I assume that
this.EmployeeUsernameAdd.Text
is the old username that you are replacing, so you should use (for example) an @OldUsername parameter.

To not change Name if the user has left the field blank, use something like ...
SQL
... Name = CASE WHEN @Name = '' THEN Name ELSE @Name END ...

Similarly for the Username and Password fields in case they are blank meaning 'no change'.
This saves you having to either dynamically create SQL or to have dozens of variants.

Put the SQL (with parameterisations) into a Stored Procedure. This will help segregate responsibilities so, for example, if you tables change name / columns are restructured, you can just change the Stored Procedure without having to edit / compile / redeploy your source code.

Finally: I hope that I have misread your SQL and you are not actually really storing passwords in plain text. I hope that the sample is just an extract and that any passwords are being saved as encrypted text, either by actually being sent encrypte (preferred) or you are using SQL Server encryption on the database itself.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900