Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Date Strings result in an out of range datetime value

Îåêßíçóå áðü ôï ìÝëïò aero. Τελευταία δημοσίευση από το μέλος Παναγιώτης Καναβός στις 18-11-2009, 14:22. Υπάρχουν 5 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  17-11-2009, 13:43 55230

    Date Strings result in an out of range datetime value

    Γεια σας

    Τρέχω το παρακάτω query σε SQl Server 2005 και μου βγάζει σφάλμα ότι  "The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value."

    SELECT DATENAME (MONTH, '13/11/2009')

    ενώ το παρακάτω query τρέχει κανονικά

    SELECT DATENAME (MONTH, '11/13/2009')

    Το collation της βάσης είναι Greek_BIN.

    Προφανώς δεν αναγνωρίζονται οι Ελληνικές ημερομηνίες απο τα strings.

    Υπάρχει τρόπος (κάποια παράμετρος στην βάση???) να αναγνωρίζονται τα Ελληνικά date strings σε ολόκληρη την βάση χωρίς να χρησιμοποιώ το SET DATEFORMAT DMY σε κάθε query

    Ευχαριστώ

     

     

     

     


    Αν γευτείς την πτήση για πρώτη φορά, περπατάς στην Γη και έχεις στραμμένα τα μάτια σου προς τον ουρανό. Γιατί εκεί ανήκεις και εκεί λαχταράς να επιστρέψεις ... Leonardo Da Vinci
  •  17-11-2009, 14:28 55231 σε απάντηση της 55230

    Απ: Date Strings result in an out of range datetime value

    Το θέμα των ελληνικών και του SQL Server (ή οποιασδήποτε εφαρμογής) έχει συζητηθεί δεκάδες φορές και η απάντηση είναι μία: Ο SQL Server δεν χρειάζεται κόλπα για να δουλέψει με ελληνικά. Όσο χρησιμοποιείς Unicode strings, parameterized queries ή έστω ISO format για τις ημερομηνίες, δεν έχεις πρόβλημα οποιοδήποτε και να είναι το collation της βάσης ή το codepage της εφαρμογής. Αν θέλεις, διάβασε το παραπάνω blog post για περισσότερες λεπτομέρειες.

    Στην περίπτωση σου αντί να γράφεις 13/11/2009, γράψε 20091113. Αν το string έρχεται από εφαρμογή, άλλαξε το query σου ώστε να δέχεται datetime παράμετρο αντί για string. Όσο για το πρόβλημα σου οφείλεται στο ότι ο SQL Server χρησιμοποιεί τα settings του connection και όχι της βάσης για να κάνει τη μετατροπή από character σε datetime. 

    Γενικά, είναι κακή πρακτική να χρησιμοποιείς αναπαραστάσεις δεδομένων σε string οι οποίες συνδέονται με μία συγκεκριμένη γλώσσα, γιατί έτσι δένεις την εφαρμογή σου με ένα συγκεκριμένο locale. Αν χρειαστεί να κάνεις deployment σε κάποιο διαφορετικό locale π.χ. σε κάποιο hoster, θα αντιμετωπίσεις προβλήματα.


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  17-11-2009, 22:41 55248 σε απάντηση της 55230

    Απ: Date Strings result in an out of range datetime value

    Ισως αν δοκίμαζες να κάνεις convert το string σε date με την CONVERT, να είχες το αποτέλεσμα που θέλεις.

    Nομίζω ότι αυτό που θέλεις είναι το CONVERT(DATETIME, '13/11/2009', 103), τσεκάρισε το στο http://msdn.microsoft.com/en-us/library/ms187928%28SQL.90%29.aspx

     

  •  17-11-2009, 23:33 55251 σε απάντηση της 55248

    Απ: Date Strings result in an out of range datetime value

    Γιατί να κάνεις convert όταν μπορείς να γράψεις την ημερομηνία σε μορφή που να την καταλαβαίνει αμέσως ο SQL Server?
    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  18-11-2009, 13:09 55260 σε απάντηση της 55251

    Απ: Date Strings result in an out of range datetime value

    α) Μπορεί να μην μπορείς να αλλάξεις τα δεδομένα σου ώστε να είναι στη μορφή που θα αναγνωρίσει ο sqlserver για να κάνει το default conversion.

    β) Για να αλλάξεις τα δεδομένα σου, θα απαιτηθεί επιπλέον κόστος (χρόνος, κώδικας, κόπος, έλεγχος), και μετά θα φάς πάλι το default conversion.

    γ) Αυτό που είναι σήμερα default θα είναι και αύριο; Στην επόμενη έκδοση του sql server; Σε ταϊλανδικό localization του sql server;

    Δεν παίζεις τυχερά παιχνίδια, κώδικα γράφεις. Γιατί να αφήσεις τα πράγματα στην τύχη τους όταν μπορείς να πεις συγκεκριμένα τι θέλεις να κάνεις;

  •  18-11-2009, 14:22 55265 σε απάντηση της 55260

    Απ: Date Strings result in an out of range datetime value

    Καταρχήν, το 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
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems