By Frank Kalis
Liest man sich die Onlinehilfe von SQL Server durch und gelangt an das Thema ISNUMERIC(), erhält man den Eindruck, daß dies eine einfache, schnelle und sichere Methode ist, um zu überprüfen, ob ein gegebener Ausdruck in einen von SQL Server unterstützten numerischen Datentypen umgewandelt werden kann. Also, in einen der Datentypen: INTEGER, FLOAT (REAL), DECIMAL (NUMERIC) und MONEY.
Unglücklicherweise nun ist aber ISNUMERIC nicht so einfach und sicher, wie man vielleicht glauben mag.
SELECT
ISNUMERIC('€+,.')
, ISNUMERIC('1d2')
, ISNUMERIC('123,45.')
----------- ----------- -----------
1 1 1
(1 row(s) affected)
Hm, laut BOL garantiert der Rückgabewert von 1, daß der Ausdruck in einen der oben angegebenen Datentypen konvertiert werden kann. Und richtig, spielt man dieses Szenario durch, erhält man folgende Antwort:
SELECT
CAST('€+,.' AS MONEY)
, CAST('1d2' AS FLOAT)
, CAST('123,45.' AS MONEY)
--------------------- ------ ---------------------
.0000 100.0 12345.0000
(1 row(s) affected)
Nun mag man sich vielleicht fragen, wo das Problem ist, und ob dies der Rede überhaupt wert ist. Ich denke, daß man sich der Eigenheiten von ISNUMERIC() bewußt sein sollte und lieber einen Blick zuviel als zuwenig auf die Basisdaten werfen sollte, bevor man hier über die Eigentümlichkeiten stolpert.
Generell kann man sich auch fragen, ob derartige Aufgaben nicht besser an den Client delegiert werden sollten. Datenbanksysteme wie der SQL Server sind nicht für derartige Aufgaben optimiert.
Falls es aber - mal wieder - unbedingt im SQL Server erledigt werden soll, kann man vielleicht folgendes machen:
SELECT
PATINDEX('%[^0-9]%', '€+,.')
, PATINDEX('%[^0-9]%', '1d2')
, PATINDEX('%[^0-9]%', '123,45.')
, PATINDEX('%[^0-9]%', '12345')
----------- ----------- ----------- -----------
1 2 4 0
(1 row(s) affected)