W SQL Server, oprócz opisanych w poprzednich artykułach, funkcjach daty i czasu, tekstowych czy matematycznych, istnieje wiele innych kategorii. Związane mogą być one z rozszerzeniami analitycznymi SQL (funkcje analityczne w SQL), bezpieczeństwem czy wyciąganiem informacji o strukturach i środowisku (metadane).
Opisywanie ich wszystkich w ramach kursu SQL dla początkujących mija się z celem. Chciałbym zwrócić Twoją uwagę na kilka dodatkowych, służących weryfikacji typu danych.
Dzięki nim możesz dokonywać podstawowego sprawdzenia typu danych, np. podczas importu z zewnętrznych źródeł (plików, innych baz danych).
Pierwszą z nich jest funkcja ISDATE ( atrybut ) – zwraca true (1) – jeśli wartość jest datą lub istnieje możliwość niejawnej konwersji na datę. Jej działanie obrazuje poniższy przykład.
-- tylko dwa ostatnie przypadki Exp5 i 6 nie są datami
-- choć obie mogą nimi być np. Exp 5 YYYYDDMM
SELECT ISDATE( getdate() ) as Exp1,
ISDATE( '2013-01-02' ) as Exp2,
ISDATE( '20130102' ) as Exp3,
ISDATE( '2013/01/02' ) as Exp4,
ISDATE( '20131402' ) as Exp5,
ISDATE( '2013 01 02' ) as Exp6
Używać jej możesz zarówno w SELECT jak i w warunkach WHERE (żeby wyfiltrować tylko takie rekordy, które mają wpisaną datę a nie jakieś inne ciągi znakowe).
Drugą funkcją sprawdzania typu danych jest ISNUMERIC ( atrybut ) – działa analogicznie jak poprzednia. Zzwraca wartość true, jeśli badany atrybut (stała, zmienna, wartość danej kolumny), jest liczbą lub może zostać niejawnie przekonwertowana na liczbę.
-- jeśli jest możliwa niejawna konwersja na dowolny typ liczbowy
-- ISNUMERIC zwróci wartość true
SELECT ISNUMERIC('133') as Exp1,
ISNUMERIC('133 ') as Exp2,
ISNUMERIC('133.1') as Exp3,
'133' + 123 as Exp4,
' 133 ' + 123.32 as Exp5,
' 133.1' - 132.1 as Exp6
Zauważ, że niektóre z tych stringów, nie do końca są poprawnymi liczbami (spacje). Jeśli jest to możliwe, silnik bazy danych wykona na nich niejawną konwersję typu na liczbowy, dlatego możliwe jest wykonanie na nich operacji matematycznych bez użycia CAST / CONVERT.
Z tą funkcją wiążą się jednak pewne zagrożenia. Jej działanie jest rozszerzone także na wartości „monetarne”. Akceptuje pewne znaki, których później nie można niejawnie przekonwertować np. na postać float, decimal czy int. Zwraca true również dla wartości zawierających takie symbole jak , . $ E + – etc..
SELECT ISNUMERIC ( '-,') as Result
Skoro jest to liczba, to dlaczego nie można zrobić tak :
SELECT '-,' + 10
Msg 245, Level 16, State 1, Line 1 Conversion failed when converting the varchar value '-,' to data type int.
Z drugiej strony, możemy najpierw przekonwertować naszą „problematyczną” liczbę na wartość typu money / smallmoney a dopiero następnie wykonywać na niej operacje matematyczne. To zadziała.
SELECT CAST('-,' as smallmoney) + 10 as Result
Na koniec, jeszcze jedna funkcja DATALENGTH ( atrybut ), która zwraca informację o faktycznej liczbie bajtów, ile zajmuje dana wartość.
Możemy przekonać się, jaka jest różnica pomiędzy ciągiem znaków zapisanych standardowo na 8 bitach (1bajt na każdy znak) versus kodowanie w UNICODE (stąd przedrostek nvarchar, nchar oraz N przed stringami) na dwóch bajtach, dla każdego znaku. Zauważ, że funkcja LEN() zwraca informację o liczbie znaków (nie bajtów).
SELECT DATALENGTH( 'Ala ma kota' ) ,
DATALENGTH( N'Ala ma kota' ) as DataLen,
LEN ( 'Ala ma kota' ) as ASCIILen,
LEN ( N'Ala ma kota' ) as UNICODELen