Το πρόβλημα είναι ο κώδικας, όχι η βάση ή η γλώσσα.
Ο SQL Server δεν χρειάζεται κάτι ιδιαίτερο για να αποθηκεύσει ελληνικά, γαλλικά ή κυριλλικά - αν τα στείλεις ως unicode. Αυτό σημαίνει ότι τα πεδία που χρησιμοποιείς πρέπει να είναι nvarchar, το string που στέλνεις να είναι nvarchar και να το στέλνεις ως Unicode (p.x. Ν'το sting μου') αντί για ASCII string. Το collation δεν παίζει κανένα ρόλο αν χρησιμοποιείς Unicode. Αν όμως προσπαθήσεις να αποθηκεύσεις σε varchar (δηλαδή ASCII) πεδίο ή στείλεις τα string με μορφή ASCII, το collation θα χρησιμοποιηθεί ως το codepage του string. Προφανώς αν το collation είναι διαφορετικό από αυτό που νομίζεις, θα έχεις πρόβλημα.
Στην περίπτωση σου το string concatenation που χρησιμοποιείς προκαλεί πολλά προβλήματα: ασφάλειας (λόγω sql injection), ταχύτητας (επειδή αναγκάζεις τον server να κάνει συνέχεια parse ένα query που μπορεί να έχει ξανασυναντήσει) και τέλος, στέλνεις τα sting ως ASCII. Επιπλέον, αν τα πεδία σου δεν είναι nvarchar, θα έχεις πρόβλημα.
Ο σωστός τρόπος είναι να φτιάξεις ένα parameterized query και να περάσεις έτσι τα string. Με τον τρόπο αυτό αποκλείεται η πιθανότητα sql injection, ο server θα ξαναχρησιμοποιήσει το ίδιο execution plan κάθε φορά ακόμα και αν αλλάξουν οι παράμετροι και δεν θα χρειαστεί να μαντέψει ούτε να κάνει καμμία μετατροποπή μεταξύ codepages:
Dim sql As String = "insert into lexis_master(ltajis_cod,Lklidi,lexis,profora,metafrasi,Lenergo,Lindex,epipedo) " &
" values(@ltajis_cod,@Lklidi,@lexis,@profora,@metafrasi,@Lenergo,@Lindex,@epipedo)"
Using connection = New SqlConnection("some connenction string")
Using cmd = New SqlCommand(sql, connection)
cmd.Parameters.AddWithValue("@ltajis_cod", "aaa")
cmd.Parameters.AddWithValue("@Lklidi", "bbb")
cmd.Parameters.AddWithValue("@lexis", "ccc")
cmd.Parameters.AddWithValue("@profora", "sdfsfs")
cmd.Parameters.AddWithValue("@metafrasi", "sdfs")
cmd.Parameters.AddWithValue("@Lenergo", "sdsds")
cmd.Parameters.AddWithValue("@Linde", "sdfsd")
cmd.Parameters.AddWithValue("@epipedo", "sdfsdfsd")
connection.Open()
cmd.ExecuteNonQuery()
End Using
End Using
Το καλό με τα parameters είναι ότι με τον ίδιο τρόπο μπορείς να περάσεις και αριθμούς και ημερομηνίες χωρίς να τα μετατρέψεις σε string, οπότε δεν έχεις πονοκεφάλους για το πως θα περάσει η υποδιαστολή ή πως γράφεται μία ημερομηνία στην Αμερική ή την Ελλάδα. Τέλος, δεν υπάρχει καμμία απολύτως ανάγκη να χρησιμοποιήσεις κάποιo SqlAdapter.
Εγκυκλοπαιδικά τέλος, για να εισάγεις ένα unicode string σε μία εντολή T-SQL πρέπει να βάλεις μπροστά από το string το γράμμα N. Θα πρέπει δηλαδή να γράψεις ... where somefield = Ν'τα ελληνικά μου' ή Values (N'κι άλλο ελληνικό',N'...'). Αυτό πρέπει να το θυμάσαι όταν γράφεις π.χ. εντολές στο Management Studio. Στον κώδικα πρέπει πάντα να χρησιμοποιείς parameterized queries.
Παναγιώτης Καναβός, Freelancer
Twitter: http://www.twitter.com/pkanavos