string not accepting " 's " while writing to database - sql

Hello everyone i am creating a settings page for another application using mvc4. In the settings page:
1.It contains two text areas wherein the user can type anything.
2.After typing if the user clicks submit button, the text he has written is saved in a sql database.
3.The main application will read that data from the database and display it.
Here are my respective codes:
Model:
public string PartnerInfo1 { get; set; }
public string PartnerInfo2 { get; set; }
Controller:
[HttpPost]
public ActionResult Index(AddDetailModel model)
{
pinfo1 = model.PartnerInfo1;
pinfo2 = model.PartnerInfo2;
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["Sample"].ConnectionString);
con.Open();
SqlCommand cmd = new SqlCommand("update dbo.Partner_Design set PartnerInfo1='" + pinfo1 + "',PartnerInfo2='" + pinfo2 + "' where [PartnerID]='cs'", con);
cmd.ExecuteNonQuery();
return RedirectToAction("Index");
}
and in the view:
#Html.TextAreaFor(m => m.PartnerInfo1)
#Html.TextAreaFor(m => m.PartnerInfo2)
in the database, the corresponding table contains two columns PartnerInfo1,PartnerInfo2 and their datatype is nvarchar(max).
My problem is when i type apostrophe in text area it gives me error.For example if i type "world's" it gives error on clicking submit button.
This is the error:
Incorrect syntax near 's'.
Unclosed quotation mark after the character string ''.
Please suggest what i can do to avoid this.Any help would be appreciated.

Never do that - it's unsafe and allow to make sql injection:
SqlCommand cmd = new SqlCommand("update dbo.Partner_Design set PartnerInfo1='" + pinfo1 + "',PartnerInfo2='" + pinfo2 + "' where [PartnerID]='cs'", con);
Instead of that use the following parameters syntax:
SqlCommand cmd = new SqlCommand("update dbo.Partner_Design set PartnerInfo1=#pinfo1, PartnerInfo2=#pinfo2 where [PartnerID]='cs'", con);
cmd.Parameters.AddWithValue("#pinfo1", pinfo1);
cmd.Parameters.AddWithValue("#pinfo2", pinfo2);

Your method expose your query to sql injection attacks. You are much better using a parameterised query which will sort out your ' issue as well.
string connString = ConfigurationManager.ConnectionStrings["Sample"].ConnectionString;
using (SqlConnection con = new SqlConnection(connString))
{
SqlCommand cmd = new SqlCommand("Update dbo.Partner_Design " +
"Set PartnerInfo1=#pinfo1, " +
"PartnerInfo2=#pinfo2 " +
"Where [PartnerID]=#partnerId", con);
cmd.Parameters.AddWithValue("#pinfo1", model.PartnerInfo1);
cmd.Parameters.AddWithValue("#pinfo2", model.PartnerInfo2);
cmd.Parameters.AddWithValue("#partnerId", "cs");
con.Open();
cmd.ExecuteNonQuery();
}

You can escape the single quote by prefixing it with another single quote, which would require doing a replace on your string before you add it to the query i.e.:
pinfo1 = pinfo1.Replace("'", "''");
pinfo2 = pinfo2.Replace("'", "''");
SqlCommand cmd = new SqlCommand("update dbo.Partner_Design set PartnerInfo1='" + pinfo1 + "',PartnerInfo2='" + pinfo2 + "' where [PartnerID]='cs'", con);
I would however strongly advise against this and take the advice of the other responses that instead use parameterised SQL which is much more secure. Note also that this solution will only solve your single quotes problem, and will still cause issues with other special characters that need escaping individually. As such whilst this should answer your question, the solutions proposed by Sławomir Rosiek and Kaf are much more comprehensive, much safer, and are best practice.
The method you are using leaves you open to SQL injection attacks.

Related

How can i make a delete query with more that 1 condition?

I need to clear a row in the SQL database. Can I do it like this?:
string idprod = Request.QueryString["IDProduto"];
string size= Request.QueryString["Size"];
try
{
liga.Open();
SqlCommand comando = new SqlCommand();
comando.CommandText = "delete FROM dbo.M16_Tbl_Carrinho where ID_User=" +
Session["IDuser"] + " and ID_Produto="+idprod+" and Tamanho="+tamanho+"";
comando.Connection = liga;
Response.Redirect("Cart.aspx");
}
catch (Exception er)
{
Response.Write($"<script>alert({er.Message});</script>");
}
Short answer: Yes, you can do it that way, but there are good reasons to not do so.
Answer to the actual question: Yes, you can put as much as you want in the WHERE clause.
Advice against SQL injection: Never, ever concatenate values in a string in this way. Use prepared parameters. Example excerpt:
liga.Open();
SqlCommand comando = new SqlCommand();
comando.CommandText = "delete FROM dbo.M16_Tbl_Carrinho where ID_User=#iduser and ID_Produto=#idprod and Tamanho=#tamanho";
comando.Parameters.Add("#iduser").Value = iduser;
comando.Parameters.Add("#idprod").Value = idprod;
comando.Parameters.Add("#tamanho").Value = tamanho;
comando.Connection = liga;
I would suggest you to look at this example: https://www.c-sharpcorner.com/UploadFile/718fc8/save-delete-search-and-update-record-in-ado-net/
It has all CRUD operations example.
Also, do not use string concatenation. Instead use Sql parameter as suggested by #Ross.
Try to separate your presentation logic from data access logic. Your one method doing lots of things.

Problem reading foreign characters Winform Textbox from database

please help. in Visual Studio 2017 and SQL localDB - WinForm learns and makes a small application. Form (Textbox), where "name, surname, address, city, phone and email" is written in Czech language containing "ěščřžýáíé" ". Everything is stored in the database (nvarchar) in order. Everything OK.
In Form2 I have another form where Combobox calls a "surname" and it has to fill in the phone and e-mail automatically from the database. If the surname is without the character "ěščřžýáíé", everything will be displayed correctly. If it contains "ěščřžýáíé", only the last name will be displayed, but the phone and email will not be loaded into the TextBox.
The code sample (without ěščřžýáíé) works perfectly:
SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\newtest.mdf;Integrated Security=True");
string sql = "select * from test111 WHERE firmadat ='" + prijmeniComboBox.Text + "'; ";
SqlCommand cmd = new SqlCommand(sql, con);
SqlDataReader myreader;
try
{
con.Open();
myreader = cmd.ExecuteReader();
while (myreader.Read())
{
string rollno = myreader.GetInt32(0).ToString();
string name = myreader.GetString(1);
string telephone = myreader.GetString(3);
string email = myreader.GetString(4);
textBox1.Text = rollno;
telefonTextBox.Text = telephone;
emailTextBox.Text = email;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
Thank you for your help.
The problem is probably here:
string sql = "select * from test111 WHERE firmadat ='" + prijmeniComboBox.Text + "'; ";
Here you take your Unicode string and you concatenate it into a SQL string that is not a Unicode string. I would tell you how to get it working as you intended but this is a really really dangerous way to write SQLs. Someone at kids' toy maker VTech wrote SQLs this way and enabled a hacker to download millions of images of children taken by vtech devices. If one of my developers wrote SQL like this they would be subject to disciplinary action, possibly being fired.
I strongly recommend that you use parameterized SQLs; any number of internet resources will show you how, such as http://bobby-tables.com - it will also solve the problem of getting no results when searching using a search term that contains non-ASCII characters
Take a look at http://dapper-tutorial.net ; using dapper will not only take care of the parameterizing for you, but make your database life easier by reducing your code to just a couple of lines, something like:
using(SqlCommand x = new SqlCommand(conn)
{
var p = x.Query(
"select * from test111 WHERE firmadat = #a",
new { a = prijmeniComboBox.Text }
);
firstNameTextBox.Text = p.FirstName; //or what the column is called on db
...
}
You just write your sql, use #namedParameter placeholders and supply an anonymous object with properties named after the placeholders. Dapper does the rest. If you have a Person class in your project you can even get dapper to create it and populate it for you

SQL Server update in C#

I try to UPDATE data in my SQL Server database and I get this error:
System.Data.SqlClient.SqlException
Incorrect syntax near 'de'
Unclosed quotation mark after the character string ')'
private void BtEnrMod_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection("Data Source=.\\BD4X4;Initial Catalog=BD4X4;Integrated Security=True");
con.Open();
SqlCommand cmd = new SqlCommand("UPDATE Service SET Type = " + TxBxService.Text + ", Prix = " + TxBxPrix.Text + "WHERE Code = " + LbCodeAff.Text + "')", con);
int i = cmd.ExecuteNonQuery();
if (i != 0)
{
MessageBox.Show("Service Modifié");
}
else
{
MessageBox.Show("Erreur");
}
this.Close();
con.Close();
}
Replace the one liner that declares your command with this code block:
SqlCommand cmd = new SqlCommand("UPDATE Service SET Type = #t, Prix = #p WHERE Code = #c", con);
cmd.Parameters.AddWithValue("#t", TxBxService.Text);
cmd.Parameters.AddWithValue("#p", TxBxPrix.Text);
cmd.Parameters.AddWithValue("#t", LbCodeAff.Text);
Always avoid writing an sql where you string concatenate in a value provided by the user in a text box; it's the number one security horror you can make with sql. Always use parameters to put values in, like you see here. For more info on this SQL injection hacking, see http://bobby-tables.com
If you ever fin yourself in a situation where you think you have to concatenate to make an sql, don't concatenate a value in; concatenate a parameter in and add the value into the parameters collection. Here's a hypothetical example:
var cmd = new SqlCommand("","connstr");
strSql = "SELECT * FROM table WHERE col IN (";
string[] vals = new[]{ "a", "b", "c" };
for(int x = 0; x<vals.Length; x++){
strSql += ("#p"+x+",");
cmd.Parameters.AddWithValue("#p"+x, vals[x]);
}
cmd.CommandText = strSql + ")";
This uses concatenation to make an sql of SELECT * FROM table WHERE col IN (#p0, #p1, #p2) and a nicely populated parameters collection
When you're done grokking that, read the link Larnu posted in the comments. There are good reasons to avoid using AddWithValue in various scenarios but it will always be preferable to concatenation of values. Never ditch the use of parameters "because I read a blog one time about how AddWithValue is bad" - form parameters using the new parameter constructor, or use AddWithValue shortcut, but never concat values
Or better still than all of this, use an ORM like Entity Framework, nHibernate or Dapper and leave most of this boring boilerplate low level SQL drudgery behind. These libraries do most of this wrangling for you; EF and nH even write th sql too, dapper you write it yourself but it takes care of everything else
Using a good ORM is like the difference between writing creating a UI manually line by line of position, font, anchor, event code for every button, label and text box versus using the windows forms designer; a world apart and there's no sense in taking hours to create manually what software can do more comprehensively, faster and safer for you in seconds

Like and = operater is not working together in signal query

I am using sap.net web form. In this web form i have a text and a button. user enter name or id and hit search button. Searching with id is working fine but with name it is not working.
What i am missing here help me out please.
String Status = "Active";
String BDstring = ConfigurationManager.ConnectionStrings["CS"].ConnectionString;
using (SqlConnection conn = new SqlConnection(BDstring))
{
try
{
String query = "SELECT * from Driver where(Name LIKE '%' + #search + '%' OR DriverID = #search) AND Status = 'Active'";
SqlCommand cmd = new SqlCommand(query, conn);
cmd.Parameters.AddWithValue("#search", SearchTextBox.Text);
conn.Open();
SqlDataReader SDR = cmd.ExecuteReader();
DataTable DT = new DataTable();
if (SDR.HasRows)
{
DT.Load(SDR);
GridView.DataSource = DT;
GridView.DataBind();
}
}
catch (SqlException exe)
{
throw exe;
}
}
}
The code is generating an exception. The fact that you're unaware of this indicates that you have "error handling" somewhere in your system that is, in fact "error hiding". Remove empty catch blocks, or pointless catch blocks such as the one in your question that just destroys some information in the exception and re-throws it. Those aren't helping you.
The actual problem is that the DriverID column is int and your parameter is varchar. So long as the varchar contains a string that can be converted to a number (which is the direction that the conversion happens in due to precedence), the query is well-formed.
As soon as the parameter contains a string that cannot be implicitly converted to a number, SQL Server generates an error that .NET turns into an exception.
For your LIKE variant, you're forcing a conversion in the opposite direction (numeric -> varchar) since LIKE only operates on strings. That conversion will always succeed, but it means that you're performing textual comparisons rather than numeric, and also means there's no possible index usage here.
I'd suggest that you change your C# code to attempt a int.TryParse on the input text and then uses two separate parameters to pass strings and (optionally) their numeric equivalent to SQL Server. Then use the appropriate parameters in your query for each comparison.
Something like:
String Status = "Active";
String BDstring = ConfigurationManager.ConnectionStrings["CS"].ConnectionString;
using (SqlConnection conn = new SqlConnection(BDstring))
{
String query = "SELECT * from Driver where(Name LIKE '%' + #search + '%' OR " +
"DriverID = #driverId) AND Status = 'Active'";
SqlCommand cmd = new SqlCommand(query, conn);
cmd.Parameters.Add("#search", SqlDbType.VarChar,50).Value = SearchTextBox.Text;
cmd.Parameters.Add("#driverId", SqlDbType.Int);
int driverId;
if(int.TryParse(SearchTextBox.Text, out driverId))
{
cmd.Parameters["#driverId"].Value = driverId;
}
conn.Open();
SqlDataReader SDR = cmd.ExecuteReader();
DataTable DT = new DataTable();
if (SDR.HasRows)
{
DT.Load(SDR);
GridView.DataSource = DT;
GridView.DataBind();
}
}
"SELECT * from Driver where (Name LIKE '%" + #search + "%'
OR DriverID = '" + #search + "' ) AND Status = 'Active'";
how about this?

Writing values to sql database

I am trying to write three variables into a database table. The code I have is:
sqlCmd.CommandText = "INSERT INTO dbo.PortfolioValues(StudentNumber,TimeStamp,PortfolioValue) VALUES(StudentNumber.ToString() , Time.ToString() , Total.ToString())" + dbConnection;
sqlCmd.ExecuteNonQuery();
sqlTran.Commit();
dbconnection is the name of the connection. It does not do anything. It is in a try-catch but goes straight to catch.
Thanks in advance.
You should
avoid concatenating together your SQL statement - avoid SQL injection attacks! Use parametrized queries instead!
use using blocks for your SqlConnection and SqlCommand objects
Try something like this:
string _connString = "........";
string queryStmt =
"INSERT INTO dbo.PortfolioValues(StudentNumber, TimeStamp, PortfolioValue) " +
"VALUES(#StudentNumber, #TimeStamp, #TotalValue)";
using(SqlConnection _con = new SqlConnection(_connString))
using(SqlCommad _cmd = new SQlCommand(queryStmt, _con))
{
// create paramters and set values
_cmd.Parameters.Add("#StudentNumber", SqlDbType.Int).Value = StudentNumber;
// do the same for the other two parameters
try
{
_con.Open();
_cmd.ExecuteNonQuery();
_con.Close();
}
catch(Exception exc)
{
// handle exception
}
}
StudentNumber.ToString() cannot be contained in a query! It's java code not sql...
//Am asuming you are using C# and the System.Data.SqlClient
//here is how you might do what you want
private static void CreateCommand(string queryString,
string connectionString)
{
using (SqlConnection connection = new SqlConnection(
connectionString))
{
SqlCommand command = new SqlCommand(queryString, connection);
command.Connection.Open();
command.ExecuteNonQuery();
}
}
//so that you use it this way:
String query = String.Formart("INSERT INTO dbo.PortfolioValues(StudentNumber,TimeStamp,PortfolioValue) VALUES(\"{0}\",\"{1}\",\"{2}\")",StudentNumber.ToString() , Time.ToString() , Total.ToString());
String connectionString = "your connection string";
CreateCommand(query,connectionString);