DATETIME and conversion to INT in SQL Server
Fivi Panopoulou - Sotiris Karras
Στην T-SQL, όπως και στις περισσότερες μοντέρνες γλώσσες προγραμματισμού, ο operator ‘+’ είναι overloaded.
Αυτό σημαίνει πως όταν τον χρησιμοποιούμε, ανάλογα το datatype των ορισμάτων, αυτός θα μας επιστρέψει και διαφορετικά αποτελέσματα.
Για παράδειγμα, όταν τον χρησιμοποιούμε με strings ορίσματα (CHAR ,VARCHAR, NVARCHAR, κ.τ.λ.) θα κάνει concatenation, ενώ όταν τον καλούμε με INTs θα εκτελέσει ακέραια πρόσθεση.
Στην σελίδα στο MSDN αναφέρονται και οι τρόποι με τους οποίους συμπεριφέρεται αν τον καλέσουμε με ορίσματα διαφορετικά datatypes (π.χ. INT + CHAR ή INT + DATETIME). Τι θα συμβεί όμως αν τον καλέσουμε με ορίσματα DATETIME; Ή αλλιώς τι αποτέλεσμα θα επιστρέψει το SELECT GETDATE() + GETDATE();
Είναι προφανές ότι η παραπάνω πράξη δεν έχει πρακτικό νόημα, καθώς από την πρόσθεση ημερομηνιών δεν προκύπτει κάποιο λογικό αποτέλεσμα. Αν όμως δώσουμε το παραπάνω query στον SQL Server, αυτός θα μας επιστρέψει αποτέλεσμα, και μάλιστα αυτό θα είναι DATETIME. Σε αυτό το post, θα μελετήσουμε το ποια είναι η σημασία του αποτελέσματος αυτού και το πώς υπολογίζεται.
Αρχικά ας τρέξουμε το παρακάτω query:
SELECT CAST('2016-04-16' AS DATETIME) + CAST('2016-04-17' AS DATETIME) AS UnknownDate;
-- UnknownDate: 2132-08-01 00:00:00.000
Ομοίως, το επόμενο query:
SELECT CONVERT(INT,CAST('2016-04-16' AS DATETIME)) AS ConvDate1, CONVERT(INT,CAST('2016-04-17' AS DATETIME)) AS ConvDate2;
-- ConvDate1: 42474, ConvDate2: 42475
Οπότε μετατρέποντας δύο DATETIME πεδία τα οποία έχουν διαφορά μίας ημέρας σε INT μας προκύπτουν δύο ακέραιοι αριθμοί που διαφέρουν και οι αυτοί κατά 1.
Υποθέτουμε λοιπόν πως η μετατροπή ενός DATETIME πεδίου σε INT, είναι ο υπολογισμός του αριθμού των ημερών που έχουν περάσει από fixed ημερομηνία. Ο πιο εύκολος τρόπος να την υπολογίσουμε είναι τρέχοντας το παρακάτω, τo οποίο μας επιστρέφει την ημερομηνία “μηδέν”:
SELECT CAST('2016-04-16' AS DATETIME) - CAST('2016-04-16' AS DATETIME) AS ZeroDate;
-- ZeroDate: 1900-01-01 00:00:00.000
Τώρα είμαστε πλέον σε θέση να κατανοήσουμε το αποτέλεσμα του πρώτου query που εκτελέσαμε. Ο SQL Server, υπολόγισε τις ημέρες που έχουν περάσει από την 01/01/1900 για τις δύο ημερομηνίες (42474 και 42475 αντίστοιχα) και στην συνέχεια υπολόγισε την ημερομηνία που θα έχουμε αφού έχουν περάσει 84949 ημέρες από αυτήν. Για του λόγου του αληθές αν τρέξουμε το παρακάτω query
SELECT DATEADD(DAY,42474+42475,'1/1/1900') AS ResolvedDate;
To αποτέλεσμα είναι το ίδιο με αυτό του πρώτου query.
Σημείωση: Το παραπάνω ισχύει για datetime μόνο. Για τα date και datetime2 data types η πράξη θα επιστρέψει σφάλμα.