Καταρχήν, το ISO και το ODBC standard είναι standard που σημαίνει ότι δεν αλλάζουν. Ο SQL Server τα υποστηρίζει με αυτή τη μορφή από την έκδοση 7 (δεν έχω δουλέψει με 6.5) και θα τα υποστηρίζει πάντα, ασχέτως localization. Δεν πρόκειται για κάποιο default το οποίο αλλάζει με το localization.
Δεύτερον, δεν μιλάμε για αλλαγή των δεδομένων αλλά για τον τρόπο με τον οποίο τα περνάει μία εφαρμογή στον SQL Server. Ο καλύτερος τρόπος είναι να περάσεις τα δεδομένα με τον πραγματικό τους τύπο μέσω παραμέτρων έτσι ώστε να αποφύγεις οποιοδήποτε πρόβλημα λόγω μετατροπής. Αυτό απαιτεί ελάχιστο έως καθόλου κώδικα: Το ADO.NET θέλει μερικές γραμμές για να ορίσεις τις παραμέτρους ενώ το LINQ to SQL και το Entity Framework δημιουργούν αυτόματα sql statements με παραμέτρους.
Αν δεν μπορείς να το κάνεις αυτό, επειδή π.χ. δουλεύεις με PHP που δεν καταλαβαίνει από παραμέτρους, περνάς τα δεδομένα με μορφή που δεν επηρεάζεται από localization. Για την ημερομηνία αυτή η μορφή είναι το ISO ή το ODBC format. Ακόμα και στην PHP όμως υπάρχουν πλέον libraries τα οποία χρησιμοποιούν παραμέτρους όταν επικοινωνούν με τη βάση.
Πρόβλημα θα υπάρξει μόνο αν έχεις ήδη προβληματικά δεδομένα. Αν για οποιοδήποτε λόγο έχεις αποθηκεύσει dates ή decimals σε πεδία (n)varchar αντί για datetime ή decimal, έχεις ήδη πρόβλημα. Εκεί πρέπει να κάνεις τις μετατροπές με το χέρι και να προσέχεις πάντα τα locales μεταξύ source, εφαρμογής, βάσης για να μην γίνει κάποιο λάθος ενδιάμεσα λόγω μετατροπής. Θα έλεγα μάλιστα ότι έχεις μεγάλο πρόβλημα επειδή η χρήση (n)varchar πεδίου για την αποθήκευση date ή decimal είναι δείγμα κακής σχεδίασης της βάσης. Σε αυτή την περίπτωση τα conversions μάλλον είναι το μικρότερο πρόβλημα που θα αντιμετωπίσεις.
Όσον αφορά τα τυχερά παιχνίδια, ακριβώς για να αποφύγεις την τυχαία μετατροπή μεταξύ locales ΔΕΝ χρησιμοποιείς localized data. Δεν υπάρχει τίποτε το τυχαίο στο '20090112'. Είναι πάντα η 12η Ιανουαρίου 2009.
Αντιθέτως, το τί σημαίνει το '12/01/2009' εξαρτάται από το web server και τον database server που χρησιμοποιείς. Ακόμα και αν βάλεις conversion στο sql statement είσαι σίγουρος ότι ο web server θα σου δώσει την ημερομηνία με αυτή τη μορφή? Τί θα συμβεί αν ο web server έχει άλλο locale από αυτό που νόμιζες? Αν ο web server έχει αγγλικό locale η 12η Ιανουαρίου θα γίνει '01/12/2009'. Αν έχει ελληνικό θα γίνει '12/01/2009'. Η μία από τις δύο μορφές θα αποτύχει όταν κάνεις το conversion με TSQL στον servers σου. Και τί θα κάνεις αν χειρίζεσαι δεδομένα από διάφορες χώρες?
Το χειρότερο που μπορεί να σου συμβεί είναι να μην καταλάβει κανείς το πρόβλημα μέχρι π.χ. να χρειαστεί να γίνει κάποιο migration ή reporting. Ακόμα χειρότερα, μπορεί να μεταφέρεις τη βάση σε νέο application server με λάθος locale και να μην καταλάβεις το πρόβλημα μέχρι της 13 του μήνα. Όταν πλέον θα έχεις μαζέψει 2 εβδομάδες συναλλαγές με διαφορετική μορφή από αυτή όλων των προηγούμενων δεδομένων. Και να σου συμβεί αυτό Δεκέμβρη, οπότε δεν θα μπορείς να ξεχωρίσεις τις παλιές (π.χ. 12 Ιανουαρίου) από τις νέες εγγραφές (1 Δεκεμβρίου).
Ακριβώς επειδή έχω δει τέτοιους τραγέλαφους, σε χρηματιστηριακές εφαρμογές και ERP, δεν χρησιμοποιώ ποτέ localized strings.
Άσε που η χρήση παραμέτρων λύνει και άλλα προβλήματα:
- Αυξάνεται η ταχύτητα επειδή ο SQL Server δεν χρειάζεται να κάνει μετατροπές και δεν χρειάζεται να φτιάξει νέο execution plan για το query
- Εξαλείφεται ο κίνδυνος SQL Injection καθώς τυχόν περίεργα strings δεν ενσωματώνονται ποτέ στο statement
Παναγιώτης Καναβός, Freelancer
Twitter: http://www.twitter.com/pkanavos