I have a database in MySQL Workbench with fields like (name, lastname, age, address, etc..) and a windows desktop application (a form) in visual studio with c# where you can insert, search and update.
When I insert data from the form and I leave some fields empty, they are saved in the database as blank and I want them to be saved as null.
Is there a way to make that happen?
Here is and insert button code:
conn = openconnection.GetConn();
MySqlCommand cmd = new MySqlCommand("INSERT INTO table_name (name,lastname,address, etc...) VALUES (' " + name_textbox.Text + " ',' " + lastname_textbox.Text + " ' etc... );", conn);
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
conn.Close();
Thanks a lot, it works fine but I have a problem with words with spaces, like: (father name , mother name , etc). When I insert a value at name it is fine but when I insert a value at father name or mother name it is null. I think it is because of space between words.
MySqlCommand cmd = new MySqlCommand("INSERT INTO table_name (name,`father name`,`mother name`, etc... VALUES (#name,#`father name`,#`mother name`,etc...);", conn);
cmd.Parameters.AddWithValue("#name", name_textbox.Text.NullString());
cmd.Parameters.AddWithValue("#`father name`", father_name_textbox.Text.NullString());
cmd.Parameters.AddWithValue("#`mother name`", mother_name_textbox.Text.NullString());
cmd.ExecuteNonQuery();
One way would be to simply do the interpretation on your own:
string.IsNullOrEmpty(name_textbox.Text) ? null : string.Format("'{0}'", name_textbox.Text);
However, I want to give you another option:
using (MySqlConnection conn = openconnection.GetConn())
{
using (MySqlCommand cmd = new MySqlCommand("INSERT INTO table_name (name,lastname,address) VALUES (#name,#lastname,#address);", conn);
{
cmd.Parameters.AddWithValue("#name", name_textbox.Text.NullString());
cmd.Parameters.AddWithValue("#lastname", lastname_textbox.Text.NullString());
cmd.Parameters.AddWithValue("#address", address_textbox.Text.NullString());
cmd.ExecuteNonQuery();
}
}
namespace System
{
public static class StringExtensions
{
public static string NullString(this string s)
{
return string.IsNullOrEmpty(s) ? null : s;
}
}
}
With this solution you'll be properly disposing the connection and command objects, but you'll also be able to streamline the string to null process and leverage prepared queries to make the process simpler and safer because it's not open to SQL Injection.
NOTE: the static class that you see should be placed in its own .cs file.
I like to use this nifty Function to test/insert DBNull.Value.
public static object ToDBNull(object value)
{
if (null != value)
return value;
return DBNull.Value;
}
Useful in other places but for your case:
MySqlCommand cmd = new MySqlCommand("INSERT INTO table_name (name,lastname,address, etc...)" +
"VALUES (' " + ToDBNull(name_textbox.Text) + " ',' " + ToDBNull(lastname_textbox.Text) + " ' etc... );", conn)
Also, you should consider your vulnerability to SQL injection attacks and consider Parameterized SQL command.
Though the columns appear as blanks in the database they are actually null. You can verify this by reading those fields in C# and comparing it with System.DBNull.
Related
This is my first time creating a web api from scratch and I'm trying to get a selected value in a drop down bow to trigger an sql search and make the appropriate item appear in a text box. below is the relevant code
protected void btnRetrieve_Click(object sender, EventArgs e)
{
try
{
string pNameTemp = DropDownList1.SelectedValue;
myConnection.Open();
string query = ("SELECT sName from [dbo].[Table] WHERE (pName LIKE " + pNameTemp + ")");
SqlCommand sqlCmd = new SqlCommand(query, myConnection);
txtSkill.Text = sqlCmd.ExecuteScalar().ToString();
myConnection.Close();
}
catch(Exception ex)
{
throw new Exception(ex.Message);
}
}
it seems to search the correct name but when it comes to updating the txtSkill, I get the exception 'invalid column name' pop up, are there any obvious reasons as to why this is happening that i'm missing? any advice would be appreciated
In fact, you are missing '' for the parameter of the query.
Try to use this query.
SqlCommand sqlCmd = new SqlCommand(#"SELECT sName from [dbo].[Table] WHERE pName LIKE '{pNameTemp}'", myConnection);
But I recommend you to use SqlParameter in C# to avoid SQL Injection
SqlCommand com = new SqlCommand("SELECT sName from [dbo].[Table] WHERE pName LIKE #field", myConnection);
myConnection.Parameters.AddWithValue("#field", pNameTemp);
But normally, when we use LIKE, we should put in % because it gives all results contains keyword. LIKE without % doesn't make sense. So :
SqlCommand com = new SqlCommand("SELECT sName from [dbo].[Table] WHERE pName LIKE #field", myConnection);
command.Parameters.AddWithValue("#field", "'%" + pNameTemp + "%'");
There are some options in the LIKE clause:
%: The percent sign represents zero, one, or multiple characters
_ The underscore represents a single character
I've been creating a class for buttons where you can add and delete rows from the table's database but it is my first time concatenate a string I have a suspicion that it is not working due to commandtext.
public static void deleteButton(string databaseName, string IDname, DataGridView dgv)
{
Helper.openConnection();
SqlCommand cmd = new SqlCommand();
cmd.Connection = Helper.cn;
string IDLocation = dgv.SelectedRows[0].Cells[0].Value.ToString();
cmd.CommandText = "delete from " + databaseName + " where " + IDname + " = " + IDLocation;
Helper.cn.Close();
MessageBox.Show("Successfully Deleted!");
}
public static void addButton(string databaseName, List<string> values, DataGridView dgv, bool isAdd)
{
Helper.openConnection();
SqlCommand cmd = new SqlCommand();
cmd.Connection = Helper.cn;
string message = isAdd == true? "Sucessfully Added" : "Sucessfully Edited";
string command = "insert into " + databaseName + " values(";
for (int i = 0; i < values.Count; i++)
{
command += values[i];
if(i != values.Count - 1) command += ", ";
}
command += ")";
cmd.CommandText = command;
MessageBox.Show(message);
Helper.cn.Close();
}
thank you for your time helping me.
Two problems:
You're using INSERT INTO [databaseName]. That should be INSERT INTO [tableName]. That's why it's not working.
Don't concatenate values into the SQL text. It opens the door for SQL injection, and it also makes it harder for the SQL server to reuse query plans. Instead, use query parameters. There is an example in the documentation.
I'll leave the design up to you and just attempt to answer the question. Have you actually looked at the command text? Have you tried to paste the command text into a query and run it manually? You need to quote string values. Also your functions and query use 'databaseName'. This should be a table name not a database name.
The commentary here is all on target, but that aside the key issue with your code is you are not doing anything. You have opened the connection, declared the SQL command, but then you don't execute it.
So yes, use parameters, but if you want your SQL to work you need to execute it:
string IDLocation = dgv.SelectedRows[0].Cells[0].Value.ToString();
cmd.CommandText = string.Format("delete from {0} where IDname = #ID", databaseName);
cmd.Parameters.AddWithValue("#ID", IDLocation);
Note you don't need quotes or anything when you use parameters, even on a non-numeric datatype.
And the feature of the evening, the missing link:
cmd.ExecuteNonQuery();
Same goes for your insert query -- be sure to run the execute method, and USE PARAMETERS!
I have a problem with executing a sql command to the DB. The command should add a new user to the 'users' table.
But when I run the code, I get this Exception on:
command.ExecuteNonQuery();
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Data.OleDb.OleDbException: Syntax error in INSERT INTO statement.
this is the code of the page - GetSignIn.cshtml :
#{
string Uname = Request["name"];
string userName = Request["userName"];
string pass = Request["passWord"];
string pic = Request["pic"];
string privacy = Request["privacy"];
if(pic == null)
{
pic = "Shared/defaultPic.jpg";
}
System.Data.OleDb.OleDbConnection connection = new System.Data.OleDb.OleDbConnection();
connection.ConnectionString = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\Etay\Documents\Visual Studio 2012\WebSites\Josef\Shared\users.mdb";
try
{
System.Data.OleDb.OleDbCommand command = new System.Data.OleDb.OleDbCommand();
command.Connection = connection;
connection.Open();
command.CommandText = "INSERT INTO users (userName,passWord,Uname,pic) VALUES ('" + userName + "', '" + pass + "', '" + Uname + "', '" + pass + "', " + pic + ")";
command.ExecuteNonQuery();
Response.Redirect("../HtmlPage.html");
}
finally
{
connection.Close();
}
}
What should I change in my code? Why is it happening? Where is the syntax error in the INSERT INTO?
Use parameterized queries. Here is your statement rewritten to make use of them.
I replaced your try/finally with a using block although your try/finally was acceptable.
Parameterized queries prevent errors and Sql Injection Attacks. An error could occur in your existing code if I were to submit a tick as a part of my user name or password. In the current form this would result in an exception. This is because the tick character is used to quote strings in sql syntax.
using (System.Data.OleDb.OleDbConnection connection = new System.Data.OleDb.OleDbConnection())
{
connection.ConnectionString = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\Etay\Documents\Visual Studio 2012\WebSites\Josef\Shared\users.mdb";
using (System.Data.OleDb.OleDbCommand command = new System.Data.OleDb.OleDbCommand())
{
command.Connection = connection;
command.CommandText = "INSERT INTO users (userName,passWord,Uname,pic) VALUES (?,?,?,?)";
command.Parameters.Add(userName);
command.Parameters.Add(pass);
command.Parameters.Add(Uname);
command.Parameters.Add(pic);
connection.Open();
command.ExecuteNonQuery();
}
}
About parameters for an OleDb connection from OleDbCommand.Parameters
Remarks
The OLE DB .NET Provider does not support named parameters for passing parameters to an SQL statement or a stored procedure called by an OleDbCommand when CommandType is set to Text. In this case, the question mark (?) placeholder must be used. For example:
SELECT * FROM Customers WHERE CustomerID = ?
Therefore, the order in which OleDbParameter objects are added to the OleDbParameterCollection must directly correspond to the position of the question mark placeholder for the parameter in the command text.
What should I change in my code?
Change to parameters (that also fixes the problem that you don;t have quotes around the pic value)
Remove the second instance of pass in your values
command.CommandText = "INSERT INTO users (userName,passWord,Uname,pic) VALUES (#userName, #pass, #Uname, #pic)";
command.Parameters.Add("#userName").Value = userName;
.. etc.
It's unclear what the type if pic is - you are passing a string but I can;t tell of the column stores a file path or if you are indending to serialize the file and store it in a pinary field.
You set 4 fields after the "INTO" clause, however you're passing 5 parameters:
"INSERT INTO users (userName,passWord,Uname,pic) VALUES ('" + userName + "', '" + pass + "', '" + Uname + "', '" + pass + "', " + pic + ")";
Just add the fifth field, or remove one parameter from the VALUES part
Please check take a look at your Insert statement, it looks like that you provided password value twice.
The number of query values and the destination fields should be same in an INSERT statement.
You have the wrong number parameters in your insert statement. For clarity, why not use string.Format to keep everything uniform? (Assuming these are all string types)
var rawSql = #"Insert INTO Users (userName,passWord,Uname,pic) VALUES ('{0}','{1}','{2}','{3}')";
command.CommandText = string.Format(rawSql, userName, pass, Uname, pic);
command.ExecuteNonQuery();
However, it also looks like you probably want to include that 5th parameter as well - just extend the format :
var rawSql = #"Insert INTO Users (userName,passWord,Uname,pic, privacy) VALUES ('{0}','{1}','{2}','{3}','{4}')";
command.CommandText = string.Format(rawSql, userName, pass, Uname, pic, privacy);
command.ExecuteNonQuery();
Since most of the answers failed to address the SQL Injection vulnerability, here's an example with parameterized queries. In addition to preventing SQL Injection attacks, it also makes it easier to troubleshoot these types of issues, and you don't need to worry about quoting or not quoting parameters.
System.Data.OleDb.OleDbConnection connection = new System.Data.OleDb.OleDbConnection();
connection.ConnectionString = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\Etay\Documents\Visual Studio 2012\WebSites\Josef\Shared\users.mdb";
try
{
System.Data.OleDb.OleDbCommand command = new System.Data.OleDb.OleDbCommand();
command.Connection = connection;
connection.Open();
command.CommandText = "INSERT INTO users (userName, passWord, Uname, pic, privacy) VALUES (?, ?, ?, ?, ?)";
command.Parameters.Add(userName);
command.Parameters.Add(pass);
command.Parameters.Add(name);
command.Parameters.Add(pic);
command.Parameters.Add(privacy);
command.ExecuteNonQuery();
Response.Redirect("../HtmlPage.html");
}
finally
{
connection.Close();
}
Tnx 4 the help
It happend to be a problem with the database - you can not apply a INSERT INTO statement where the column name is "password". "password" is a Reserved word
in SQL.
Tnx again,
Etay
This had to be a simple, ordinary SQL insert method but when I run it and I click "button1" I get the error
An unhandled exception of type 'system.data.sqlclient.sqlexception' occurred in system.data.dll
Does anyone know what the problem is?
namespace InsertDeleteUpdate_Login
{
public partial class Form1 : Form
{
SqlConnection cn = new SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=E:\C #\InsertDeleteUpdate-Login\InsertDeleteUpdate-Login\Database1.mdf;Integrated Security=True");
SqlCommand cmd = new SqlCommand();
SqlDataReader dr;
public Form1()
{
InitializeComponent();
cmd.Connection = cn;
}
private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text != "" && textBox2.Text != "")
{
cn.Open();
cmd.CommandText = "INSERT INTO info (ID,Name,Password)" + " VALUES ('" + textBox1.Text + "','" + textBox2.Text + "','" + textBox3.Text + "')'";
cmd.ExecuteNonQuery();
cmd.Clone();
MessageBox.Show("Inserare reusita");
cn.Close();
}
}
}
}
The root cause of your problem is that you are not using parameterized queries and are trying to create an sql string on the fly. As a result you make an error in the assembling code of that string. But if you use a parameterized query the chance of running into an issue like that is a lot lower because you don't have to mess about with quotes and the like. On top of this, you cannot have a sql injection attack if you use parameters and it makes the code more readable too.
Read http://www.dotnetperls.com/sqlparameter on how to use a parameterized query the way it should be done and don't just fix the textual error in the querystring. It is not the way it is supposed to be done.
This is a good explanation too : http://www.dreamincode.net/forums/topic/268104-parameterizing-your-sql-queries-the-right-way-to-query-a-database/
I can't add comments yet, but it looks like you might have an extra single quote after the last close bracket that shouldn't be there.
As mentioned by several people above, you should ALWAYS parameterise your queries, and you also have a trailing single quote, which is most likely what SQL Server is choking on.
Try something like this:
cmd.CommandText = "INSERT INTO info (ID, Name, Password) VALUES (#ID, #Name, #Password)";
cmd.Parameters.AddWithValue("#ID", textBox1.Text);
cmd.Parameters.AddWithValue("#Name", textBox2.Text);
cmd.Parameters.AddWithValue("#Password", textBox3.Text);
cmd.ExecuteNonQuery();
I have a sql select statement in my VS2005 C# server-side coding for a web application and I am meeting some errors.
Below is a screenshot of the controls in the webpage:
Data Source SqlDataSource1 : Query:SELECT [Name] FROM [Users].
Dropdownlist UserNameList : Lists all userName retrieved from SqlDataSource1.
Checkboxes AdminCb and UserCb : Automatically checks if the userType of the userName is as.
Button loadUser : Gets the user type and checks the check boxes accordingly.
Below is my code for my loadUser button
SqlConnection conn = new SqlConnection("Data Source=DATASOURCE");
string sql = string.Format("SELECT [User Type] FROM [Users] where Name like " + UserNameList.Text);
SqlCommand cmd = new SqlCommand(sql, conn);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
if(sql== "Administrator"){
AdminCb.Checked=true;
}
if(sql== "User"){
UserCb.Checked=true;
}
Currently I am stuck with the error (Wong is the 2nd word of the user's name):
Questions:
1) How can change my Sql query so that it can take in more than 1word?
2) And will I be able to check boxes once I am able to run my sql query?
Thank You.
You must have to use Parameter and call the ExecuteScalar() method instead of ExecuteNonQuery().
string sql = "SELECT [User Type] FROM [Users] where [Name]=#Name";
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.Add("#Name",SqlDbType.VarChar,50).Value=UserNameList.Text;
conn.Open();
Object result=cmd.ExecuteScalar();
conn.Close();
if(result!=null)
{
string usertype=result.ToString();
if(usertype=="Administrator")
{}
else
{}
}
In case, if result returned from the database contains more then one rows then use ExecuteReader() method.
string sql = "SELECT [User Type] FROM [Users] where [Name] like #Name";
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.Add("#Name",SqlDbType.VarChar,50).Value="%" + UserNameList.Text + "%";
conn.Open();
SqlDataReader result=cmd.ExecuteReader();
while(result.Read())
{
///
}
result.Close();
conn.Close();
Since you are concatenating the SQL string, if the input itself has a single quote in it, it thinks this is the end of the input, and the continuing input is SQL statements, which is why you may be getting that error.
Switch to using a parameter, or make sure any single quotes are escaped as a pair of single quotes, like:
string sql = string.Format("SELECT [User Type] FROM [Users] where Name like " + UserNameList.Text.Replace("'", "''"));
Since the error is indicating there is something wrong with the Name, I would take a closer look at this line:
string sql = string.Format("SELECT [User Type] FROM [Users] where Name like " + UserNameList.Text);
If you are using string.Format, you might as well use it
string sql = string.Format("SELECT [User Type] FROM [USERS] where Name like {0}", UserNameList.Text);