Η μετατροπή απέτυχε κατά τη μετατροπή της ημερομηνίας ή/και της ώρας από συμβολοσειρά χαρακτήρων κατά την εισαγωγή datetime

Προσπαθούσα να δημιουργήσω έναν πίνακα ως εξής,

create table table1(date1 datetime,date2 datetime);

Πρώτα προσπάθησα να εισαγάγω τιμές όπως παρακάτω,

insert into table1 values('21-02-2012 6:10:00 PM','01-01-2001 12:00:00 AM');

Έδωσε σφάλμα λέγοντας,

Δεν είναι δυνατή η μετατροπή varchar σε datetime

Στη συνέχεια, δοκίμασα την παρακάτω μορφή, όπως προτείνεται από το stackoverflow,

insert into table1 values(convert(datetime,'21-02-2012 6:10:00 PM',5)
                          ,convert(datetime,'01-01-2001 12:00:00 AM',5));

Αλλά εξακολουθώ να λαμβάνω το σφάλμα που λέει: "Το σφάλμα είναι το εξής,

Αποτυχία μετατροπής κατά τη μετατροπή ημερομηνίας ή/και ώρας από συμβολοσειρά χαρακτήρων

Καμία πρόταση;

Λύση

Υπάρχουν πολλοί μορφότυποι που υποστηρίζονται από τον SQL Server - ανατρέξτε στα MSDN Books Online on CAST and CONVERT. Οι περισσότερες από αυτές τις μορφές εξαρτώνται από τις ρυθμίσεις που έχετε - επομένως, αυτές οι ρυθμίσεις μπορεί να λειτουργούν κάποιες φορές - και κάποιες φορές όχι.

Ο τρόπος επίλυσης αυτού του προβλήματος είναι η χρήση της (ελαφρώς προσαρμοσμένης) μορφής ημερομηνίας ISO-8601 που υποστηρίζεται από τον SQL Server - αυτή η μορφή λειτουργεί πάντα - ανεξάρτητα από τις ρυθμίσεις γλώσσας και μορφής ημερομηνίας του SQL Server.

Η μορφή ISO-8601 που υποστηρίζεται από τον SQL Server έχει δύο εκδοχές:

  • YYYYMMDD για απλές ημερομηνίες (χωρίς τμήμα ώρας)- σημειώστε εδώ: όχι παύλες!, αυτό είναι πολύ σημαντικό! Το YYYY-MM-DD είναι ΔΕΝ ανεξάρτητο από τις ρυθμίσεις μορφής ημερομηνίας στον SQL Server σας και ΔΕΝ λειτουργεί σε όλες τις περιπτώσεις!

ή:

  • Σημειώστε εδώ: αυτή η μορφή έχει παύλες (αλλά μπορούν να παραλειφθούν), και ένα σταθερό "Τ" ως διαχωριστικό μεταξύ του τμήματος της ημερομηνίας και της ώρας του "DATETIME" σας.

Αυτό ισχύει για τον SQL Server 2000 και νεότερες εκδόσεις.

Έτσι, στη συγκεκριμένη περίπτωσή σας - χρησιμοποιήστε αυτές τις συμβολοσειρές:

insert into table1 values('2012-02-21T18:10:00', '2012-01-01T00:00:00');

και θα είστε μια χαρά (σημείωση: πρέπει να χρησιμοποιήσετε τη διεθνή 24-ωρη μορφή και όχι τη 12-ωρη μορφή AM/PM για αυτό).

Εναλλακτικά: αν είστε σε SQL Server 2008 ή νεότερο, θα μπορούσατε επίσης να χρησιμοποιήσετε τον τύπο δεδομένων DATETIME2 (αντί του απλού DATETIME) και η τρέχουσα INSERT σας θα λειτουργούσε χωρίς προβλήματα! :-) Ο τύπος DATETIME2 είναι πολύ καλύτερος και πολύ λιγότερο επιλεκτικός στις μετατροπές - και είναι οι συνιστώμενοι τύποι δεδομένων ημερομηνίας/ώρας για τον SQL Server 2008 ή νεότερους έτσι κι αλλιώς.

SELECT
   CAST('02-21-2012 6:10:00 PM' AS DATETIME2),     -- works just fine
   CAST('01-01-2012 12:00:00 AM' AS DATETIME2)   -- works just fine  

Μη με ρωτήσετε γιατί όλο αυτό το θέμα είναι τόσο δύσκολο και κάπως συγκεχυμένο - έτσι είναι. Αλλά με τη μορφή YYYYMMDD, θα πρέπει να είστε εντάξει για οποιαδήποτε έκδοση του SQL Server και για οποιαδήποτε ρύθμιση γλώσσας και μορφής ημερομηνίας στον SQL Server σας.

Σχόλια (3)

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

Παράδειγμα:

Δημιουργία πίνακα MyTable (MyDate);

Insert Into MyTable(MyDate) Values ('2015-02-29');

Ο διακομιστής SQL θα εκπέμψει το ακόλουθο σφάλμα:

Αποτυχία μετατροπής κατά τη μετατροπή της ημερομηνίας ή/και της ώρας από συμβολοσειρά χαρακτήρων.

Ο λόγος για αυτό το σφάλμα είναι ότι απλά δεν υπάρχει τέτοια ημερομηνία (29 Φεβρουαρίου) στο έτος (2015).

Σχόλια (2)

Απλή απάντηση - το 5 είναι ιταλικό "yy" και το 105 είναι ιταλικό "yyyy". Επομένως:

SELECT convert(datetime,'21-02-12 6:10:00 PM',5)

θα λειτουργήσει σωστά, αλλά

SELECT convert(datetime,'21-02-12 6:10:00 PM',105)

θα δώσει σφάλμα.

Ομοίως,

SELECT convert(datetime,'21-02-2012 6:10:00 PM',5)

θα δώσει σφάλμα, ενώ

SELECT convert(datetime,'21-02-2012 6:10:00 PM',105)

θα λειτουργήσει.

Σχόλια (0)