1

Here is my code which inserts into database the elements in the textboxes of a dynamic gridview. The code works perfectly but my problem is that the inserted elements that are typed in non-latin characters (greek characters) does not appear propely in database and instead they appear like that:

https://i.stack.imgur.com/pwVTf.jpg

Please can you tell me what to do in order to insert the greek characters properly? Here is the code:

private void InsertRecords(StringCollection sc)
    {
        StringBuilder sb = new StringBuilder(string.Empty);
        string[] splitItems = null;
        const string sqlStatement = "INSERT INTO P_interventions (Date,P_Id,Simeio,Aitio,Etos,Therap) VALUES";
        int id = Convert.ToInt32(Session["pa_id"]);
        foreach (string item in sc)
        {
            if (item.Contains(","))
            {
                splitItems = item.Split(",".ToCharArray());
                sb.AppendFormat("{0}(@Date, @p_id ,'{1}','{2}','{3}','{4}'); ", sqlStatement, splitItems[0], splitItems[1], splitItems[2], splitItems[3]);
            }
        }

        using (SqlConnection connection = new SqlConnection(GetConnectionString()))
        {
            connection.Open();
            using (SqlCommand cmd = new SqlCommand(sb.ToString(), connection))
            {
                cmd.Parameters.AddWithValue("@p_id", id);
                cmd.Parameters.AddWithValue("@Date", DateTime.Now.ToShortDateString());
                cmd.CommandType = CommandType.Text;
                cmd.ExecuteNonQuery();
            }
        }
        lblMessage.ForeColor = System.Drawing.Color.Green;
        lblMessage.Text = "The records have benn inserted successfuly!";
    }

 protected void BtnSave_Click(object sender, EventArgs e)
    {
        //εγχειρήσεις
        int rowIndex = 0;
        StringCollection sc = new StringCollection();
        if (ViewState["CurrentTable"] != null)
        {
            DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
            if (dtCurrentTable.Rows.Count > 0)
            {
                for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
                {
                    //extract the TextBox values  
                    TextBox box1 = (TextBox)Gridview1.Rows[rowIndex].Cells[1].FindControl("TextBox1");
                    TextBox box2 = (TextBox)Gridview1.Rows[rowIndex].Cells[2].FindControl("TextBox2");
                    TextBox box3 = (TextBox)Gridview1.Rows[rowIndex].Cells[3].FindControl("TextBox3");
                    DropDownList ddl2 = (DropDownList)Gridview1.Rows[rowIndex].Cells[4].FindControl("DropDownList2");
                    //get the values from TextBox and DropDownList  
                    //then add it to the collections with a comma "," as the delimited values  
                    sc.Add(string.Format("{0},{1},{2},{3}", box1.Text, box2.Text, box3.Text, ddl2.SelectedItem.Text));
                    rowIndex++;
                }
                //Call the method for executing inserts  
                InsertRecords(sc);
            }
        }
natso
  • 97
  • 1
  • 12
  • When you retrieve that data, is it shown correctly in your application? – Steve Dec 25 '15 at 17:24
  • @Steve no... they are not shown correctly even from the retrieve – natso Dec 25 '15 at 17:31
  • 1
    `"{0}(@Date, @p_id ,'{1}','{2}','{3}','{4}'); "` is wrong. You should pass the last four elements via parameters too. – Martin Smith Dec 25 '15 at 17:32
  • @MartinSmith I am not sure what do you mean. I have already passed them through parameters. Check please the last lines of my code – natso Dec 25 '15 at 17:35
  • what datatype are you using for store this characters in db. – Pankaj Gupta Dec 25 '15 at 17:40
  • 2
    You aren't passing them as parameters. You are passing them as varchar string literals. You have no `@xxx` and no `cmd.Parameters.Add` for those. As well as using incorrect datatype your approach is open to SQL injection. – Martin Smith Dec 25 '15 at 17:43
  • @PankajGupta I am using nchar. Is there any other suggestion? – natso Dec 25 '15 at 17:44
  • @MartinSmith So how passing them through parameters will help my problem? – natso Dec 25 '15 at 17:51
  • @Steve How can I see that? (Sorry I am a beginner in C#) – natso Dec 25 '15 at 17:52
  • i think nchar is correct but better use nvarchar , but problem in your case you string in ascii format not unicode fomat, i would recommend you try to direct insert this string in db with prefix with "N'Paste you string there'" and see what result you will get , i think it will work for you – Pankaj Gupta Dec 25 '15 at 17:52
  • 1
    Because you would declare the parameters as nvarchar rather than varchar. It also fixes the other problem of SQL injection that you didn't know you had at the same time. In 2015 there is no excuse for writing this type of SQL injection prone code. – Martin Smith Dec 25 '15 at 17:54
  • for future reference http://www.sqlservercentral.com/Forums/Topic1245107-392-1.aspx http://www.sqlservercentral.com/Forums/Topic1159342-391-1.aspx You can follow these link it will sort out your problem. – Pankaj Gupta Dec 25 '15 at 18:02
  • @PankajGupta I havent heard of The 'N'Paste but i will try to find it. Thanks! – natso Dec 25 '15 at 18:03
  • @MartinSmith Thank you for your advice! – natso Dec 25 '15 at 18:04
  • suffix your string with N after that in single quotes paste your string it will work, and run query directly in sqlserver and see it's storing the data successfully or not. For eg insert into table values(N'asdsnk') something like that – Pankaj Gupta Dec 25 '15 at 18:05
  • 1
    I hope you take it and don't just slap an `N` prefix there. Otherwise your site will certainly get hacked if it is on the Internet from one of the many automated crawlers looking for these vulnerabilities. – Martin Smith Dec 25 '15 at 18:06
  • 1
    @PankajGupta STOP TEACHING BAD HABBITS. – Phill Dec 25 '15 at 18:11
  • @Phill , what i know i described if anything wrong there so better explain don't blame because this field for continuos learner, so better explain why it's not good idea instead of blaming – Pankaj Gupta Dec 25 '15 at 18:14
  • 1
    Because string concatenation is prone to sql injection. Those parameters should be parameterized. End of story. You're teaching him to bypass good practice. So yes I'm blaming you for teaching bad habbits. – Phill Dec 25 '15 at 18:16

2 Answers2

3

Since you use nchar fields in your database (as mentioned in a comment), your database already supports Unicode strings. However, you are passing the values you want to insert as non-Unicode string literals in your SQL:

'...'

You need to pass them as Unicode strings:

N'...'

Now don't just put an N in front of your string literals: There's something else you are doing wrong: You are passing user-supplied values by string concatenation, which is a serious security and stability issue. Use parameters instead - you already know how to work with parameters, since you do it for @p_id and @Date. Do the same for your string values. This will also fix the Unicode issue, since AddWithValue defaults to a Unicode parameter type for strings.

Community
  • 1
  • 1
Heinzi
  • 167,459
  • 57
  • 363
  • 519
-1

I think you have to use the Unicode data types in the database instead of the regular ones (ex:instead of Varchar use NVarchar).

Also in the your code use the N before the string fields Like

 sb.AppendFormat("{0}(@Date, @p_id ,N'{1}',N'{2}',N'{3}',N'{4}'); ", sqlStatement, splitItems[0], splitItems[1], splitItems[2], splitItems[3]);
Tareq
  • 1,397
  • 27
  • 28