How to use writing N for insert query in .NET C#? - c#

In SQL Server
update incident_info
set description = N'ဆေးလိပ်'
where incidentid = 5
This query is correct in SQL Server and shows myanmar font correctly in the database.
I want to write correct query as above in below insert query.
sqlUtil.SqlDataUpdate(false, ("INSERT INTO Incident_Info (incidentid, incidentdate, incidenttime, description, Salesmen_id, name, phone, email, address, cost, currency, solution, status)" +
"VALUES (#incidentid, #incidentdate, #incidenttime, N'+#description+', #salesmenid, N'+#name+', #phone, #email, N'+#address+', #cost, #currency, N'+#solution+', #status)"), SysController.dicParams);

You do NOT need to prefix your SQL parameter names with a N prefix - that's useless, and probably results in an error. The N prefix is only needed when specifying a Unicode string literal in a raw SQL code snippet.
In your case, what you need to ensure is that the code that does the actual insert into SQL Server properly defines your parameters as SqlDbType.NVarChar. So in your sqlUtil class, somewhere, you have a method SqlDataUpdate that parses and executes that SQL statement you send in.
Inside there, you must ensure that code something like this is used:
using (SqlConnection conn = new SqlConnection(-your-connection-string-here-))
using (SqlCommand insertCmd = new SqlCommand(sqlQuery, conn))
{
// here, you need to ensure you define your string parameters correctly
insertCmd.Parameters.Add("#description", SqlDbType.NVarChar, 100);
.....
// and then you need to set the values - since .NET strings are inherently Unicode, no special treatment is needed
insertCmd.Parameters["#description"].Value = SysController.dicParams.......
.....
// open, execute, close
conn.Open();
int rowsInserted = insertCmd.ExecuteNonQuery();
conn.Close();
}
This must be done inside your sqlUtil class - you cannot influence this from the "outside" by simply adding a N prefix to your parameter names...

Related

Query updates all of my data instead of only the one I want

How do I make it so that my query only update the data I want?
Here's the current code
string query = string.Format("update Customer set title='{0}',[Name]='{1}'",titleComboBox2.Text,nameTextBox2.Text,"where ID="+idTextBox+"");
Apparently the last part of the query isn't working. Why it is that?
Because you didn't use any index argument as {2} for your third argument which is WHERE part.
That's why your query will be contain only update Customer set title='{0}',[Name]='{1}' part this will be update for your all rows since it doesn't have any filter.
Fun fact, you could see this as query if you would debug your code.
But more important
You should always use parameterized queries. This kind of string concatenations are open for SQL Injection attacks.
Let's assume you use ADO.NET;
using(var con = new SqlConnection(conString))
using(var cmd = con.CreateCommand())
{
cmd.CommandText = #"update Customer set title = #title, [Name] = #name
where ID = #id";
cmd.Paramter.Add("#title", SqlDbType.NVarChar).Value = titleComboBox2.Text;
cmd.Paramter.Add("#name", SqlDbType.NVarChar).Value = nameTextBox2.Text;
cmd.Paramter.Add("#id", SqlDbType.Int).Value = int.Parse(idTextBox.Text);
// I assumed your column types.
con.Open();
cmd.ExecuteNonQuery();
}
Currently your query does not use WHERE clause, because it is ignored by string.Format. You have 3 placeholder parameters, and you are using only {0} and {1}, so WHERE part is never added to the SQL query. Change your query to include WHERE clause, e.g. like this:
string query = string.Format("update Customer set title='{0}',[Name]='{1}' {2}",titleComboBox2.Text,nameTextBox2.Text,"where ID="+idTextBox.Text+"");
However, there is one very serious flaw in your code - it is vulnerable to SQL injection attack. There are hundreds of articles about it online, make sure to read about what that is and how to update your code accordingly (hint - parametrize queries)

sql statement does not work on specific table

I Have a website which creates new order and saves shopping bag items into database.
The thing is that insert into,select,update,delete sentences are working in all my tables except one, i think i wrote the sentence perfectly but its still throw excption that says something wrong with the sentence.
string OrderSql = string.Format(#"
INSERT INTO Order ([UserID],[DayMonthYear],[PriceToPay],[StatusID],[AdressToSend])
VALUES ({0},{1},{2},{3},'{4}')",
UserId, DateTime.Now, Price, 1, Address);
at first i thought the problem may be found at the db so i copied my db into new once still doesnt working
i would send the relationship between tables but i need 10 rep..
It looks like you have two issues. Firstly as #juergen points out in the comments order is a reserved word so you'll need to enclose it in square brackets. Secondly, you don't have the date enclosed in quotes. So your code should read:
string OrderSql = string.Format(#"INSERT INTO [Order] ([UserID],[DayMonthYear],[PriceToPay],[StatusID],[AdressToSend])
VALUES ({0},'{1}',{2},{3},'{4}')", UserId, DateTime.Now, Price, 1, Address);
Note the square brackets around Order and the single quotes around {1}.
However, you are open to SQL Injection attacks using that code so I would strongly suggest you read up on using parameterized queries. #DJ KRAZE has added a link in the comments to this question which should point you in the right direction.
you can also create a method call it and do something like this.
This would require that you create a stored procedure with the #Parameters shown in this example ** if this is Access then petelids Answer will be a great starting point if this is SQL Server then what I have posted would work for you
private void InsertMyData(string UserId, DateTime DayMonthYear, double Price, string Address)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand("INSERT INTO [Order] ([UserID],[DayMonthYear],[PriceToPay],[StatusID],[AdressToSend])
VALUES (#UserId, #DayMonthYear, #Price, 1, #Address)";
cmd.CommandType = CommandType.Text;
cmd.Connection = connection;
cmd.Parameters.AddWithValue("#UserId", UserId);
cmd.Parameters.AddWithValue("#DayMonthYear", DayMonthYear);
cmd.Parameters.AddWithValue("#PriceToPay", Price);
cmd.Parameters.AddWithValue("#StatusID", 1);
cmd.Parameters.AddWithValue("#AdressToSend", Adress);
connection.Open();
cmd.ExecuteNonQuery();
}
}

Creating Registration form in c# with mysql

Hello so i m creating a registration form in C# with MySql so it connects to the database and everything but i get this error Napaka pri registraciji Unknown column " in 'field list' the translation of Napaka pri registraciji means Error at registering i just have it in my language. I get this error when i insert data in textboxes and press Register..
the code:
private void btn_Reg_Click(object sender, EventArgs e)
{
MySqlConnection dataConnection = new MySqlConnection();
dataConnection.ConnectionString = "datasource=localhost;port=3306;username=root;password=";
dataConnection.Open();
MySqlTransaction transakcija = dataConnection.BeginTransaction();
MySqlCommand dataCommand = new MySqlCommand();
dataCommand.Connection = dataConnection;
dataCommand.Transaction = transakcija;
try
{
dataCommand.CommandText = "Insert INTO lr.users (upIme,geslo) VALUES (`"+this.tB_upIme.Text+"`,`"+this.tB_geslo.Text+"`)";
dataCommand.CommandType = CommandType.Text;
dataCommand.ExecuteNonQuery();
transakcija.Commit();
MessageBox.Show("Registracija uspešna!");
}
catch (Exception eks)
{
transakcija.Rollback();
MessageBox.Show("Napaka pri registraciji\n" + eks.Message);
}
finally
{
dataCommand.Connection.Close();
}
}
There are two things I immediately see wrong here...
First, you're using back ticks to wrap your values. In MySQL Back ticks represent database objects, so the query is looking for objects named by those values instead of using the values themselves. So instead of this:
`"+this.tB_upIme.Text+"`
You'd want this:
'"+this.tB_upIme.Text+"'
Second, and vastly more importantly, your code is wide open to SQL injection attacks. You'll want to use query parameters, not direct string concatenation. While it may look like you're just putting values into the query string, you're actually taking user input and treating it as executable code in your query string, which means users can run any arbitrary code they want on your database.
First, add parameters to your query:
"Insert INTO lr.users (upIme,geslo) VALUES (#upIme, #geslo)"
(You'll notice this also makes the query a heck of a lot cleaner and easier to read.) Then add your parameters to the command:
dataCommand.Parameters.AddWithValue("#upIme", this.tB_upIme.Text);
dataCommand.Parameters.AddWithValue("#geslo", this.tB_geslo.Text);
Then when you execute that command it will treat the user-input values as values instead of as executable code.
Change to single quotes ' in the values.
dataCommand.CommandText =
"Insert INTO lr.users (upIme,geslo)
VALUES ('"+this.tB_upIme.Text+"','"+this.tB_geslo.Text+"');";

Whitespace in SQL with C#

I have a Windows application written in C# which connect to SQL database.
I have text fields inside my application and update the database like this:
string name = textBox60.Text;
string sql = "insert into myTable(Name) values ('" + name + "')";
DbHelper.ExecuteNonquery(sql);
public static int ExecuteNonquery(string sql)
{
using (SqlConnection cn = new SqlConnection(constr))
{
if (cn.State == ConnectionState.Closed)
{
cn.Open();
}
else if (cn.State == ConnectionState.Open)
{
cn.Close();
cn.Open();
}
else if (cn.State == ConnectionState.Broken)
{
cn.Close();
cn.Open();
}
using (SqlCommand cm = new SqlCommand(sql, cn))
{
return cm.ExecuteNonQuery();
}
}
}
But for every data with type nchar in the database, they are full of white spaces. For example if I fill in abc in the text field, when I check the database it will become "abc___________________" (white spaces) something like this.
How to prevent this other than trim the string only when I read them or to use UPDATE data SET TRIM(data) if I have tons of such data.
Thanks for help.
But for every data with type nchar in the database, they are full of whitespaces.
Yup, that's because the nchar type is a fixed-width type. You're basically telling the database that you want every value for that field to have a length of 20 (or whatever it's set to). You should use nvarchar instead, which is a variable width field.
You should also avoid writing code like this:
string sql = "insert into myTable(Name) values ('" + name + "')";
Instead, you should use parameterized SQL, putting a placeholder parameter in the SQL itself, and then setting the value for the parameter in the command. This will avoid SQL injection attacks, data conversion issues, and keep your code (the SQL) cleanly separated from the data (the parameters). It will mean you need to change your helper method though. (Your helper method looks pretty odd to start with - surely when you've just created your connection, you just need to open it... is that code left over from a time when you didn't create a new connection object on each call?)
Because you've declared the database table using a char(n) rather than a varchar(n), it is always a fixed length, and if you provide a shorter string, then it will be padded with spaces.
If you don't want the spaces, declare the column as varchar(n).
Also, I'm not sure what all of the ceremony is that you're doing with the connection before you use it, but it seems mostly pointless. You've just called new SqlConnection(...). Practically by definition, this means that cn will be closed - there's no need to check its status. Just call Open() on it and move on to creating your command.
(All of the above is predicated on the column being declared as char(n). If it's nchar(n) then you should switch to nvarchar(n)).

i'm lost: what is wrong with this ado.net code?

well, the question is clear i hope, the code is this:
string sql = "delete from #tabelnaam";
SqlCommand sc = new SqlCommand();
sc.Connection = getConnection();
sc.CommandType = CommandType.Text;
sc.CommandText = sql;
SqlParameter param = new SqlParameter();
param.Direction = ParameterDirection.Input;
param.ParameterName = "#tabelnaam";
param.Value = tableName;
sc.Parameters.Add(param);
OpenConnection(sc);
sc.ExecuteScalar();
tableName is supplied to this function.
I get the exception:
Must declare the table variable #tabelnaam
IIRC, you cant use a substitute the table name for a parameter.
Rather build the SQL string containing the correct table name.
Make to changes
rather than using paramter use this
string sql = string.format( "delete from {0}",tableName);
make use of executenonquery intead of ExecuteScalar
sc.ExecuteNonQuery();
As mentioned by others, you can't parameterise the table name.
However, as you rightly mention in comments on other answers, using simple string manipulation potentialy introduces a SQL injection risk:
If your table name input is fro an untrusted source, such as user input, then using this:
string sql = string.format( "DELETE FROM {0}",tableName);
leaves you open to the table name "myTable; DROP DATABASE MyDb" being inserted, to give you:
DELETE FROM myDb; DROP DATABASE MyDB
The way round this is to delimit the table name doing something such as this:
string sql = string.format("DELETE FROM dbo.[{0}]", tableName);
in combination with checking that the input does not contain either '[' or ']'; you should probably check it also doesn't contain any other characters that can't be used as a table name, such as period and quotes.
I dont think you can parameterize the table name. From what I have read you can do it via Dynamic sql and calling sp_ExecuteSQL.
Your SQL is incorrect, you are deleting from a table variable yet you haven't defined that variable.
Update: as someone has pointed out, you are trying to dynamically build a query string but have inadvertantly used SQL parameters (these do not act as place holders for string literals).
More here:
Parameterise table name in .NET/SQL?
You cannot parameterise the table name, you have to inject it into the command text.
What you can and should do is protect yourself against SQL injection by delimiting the name thus:
public static string Delimit(string name) {
return "[" + name.Replace("]", "]]") + "]";
}
// Construct the command...
sc.CommandType = CommandType.Text;
sc.CommandText = "delete from " + Delimit(tableName);
sc.ExecuteNonQuery();
See here and here for more background info.

Categories