Leere Strings und implizite Datentyp Konvertierung

By Frank Kalis

Posted on Aug 27, 2010 von in SQL Server

Angenommen wir haben folgende Ausgangssituation:

create table mytable
(
	a int
)
insert into mytable(a) values(0)

Und wir wollen nun die Daten abfragen.

select A
from myTable
where A=0

A           
----------- 
0

So, genauso wie es sein soll, oder? Hm, aber warum verhalten sich dann folgende Abfrage so, wie sie es tun?

select A
from myTable
where A=''
select A
from myTable
where A=' '

A           
----------- 
0

A           
----------- 
0

Eine gute Frage! Die Antwort stellen wir noch ein bißchen zurück. Es wird sogar noch interessanter:

select A
from myTable
where A=Replicate(' ',8000)

A           
----------- 
0

??? Fragen über Fragen. Und die Antwort?

Nun, soweit ich das beurteilen kann, liegt die Antwort in diesem Verhalten:

select cast('' as int)

----------- 
0

Ein leerer String wird also in einen Integer Wert konvertiert!

Aha, daß das so ist, kann man in BOL nachlesen unter Rangfolge der Datentypen. Ein niedrigerer wird immer in einen höheren konvertiert. Demnach sind alle Abfragen weiter oben identisch.

Warum liefert aber auch die letzte Abfrage mit den 8.000 Leerzeichen ein Ergebnis?

Die Antwort darauf, denke ich, findet sich im SQL 92 Standard, wonach alle führenden und nachfolgenden Leerzeichen aus Strings entfernt werden sollen, bevor diese zu Zahlen konvertiert werden. Also wird aus dem String wieder ein '' und damit eine 0.

Interessanterweise funktioniert dies auch mit FLOAT und REAL, aber nicht mit DECIMAL und NUMERIC. Wenn man nun ganz spitzfindig ist, kann man dies auch aus BOL herauslesen. Unter "CAST und CONVERT" steht dort:

"SQL Server gibt eine Fehlermeldung zurück, wenn nicht numerische char-, nchar-, varchar- oder nvarchar-Daten in int-, float-, numeric- oder decimal-Daten konvertiert werden. SQL Server gibt auch einen Fehler zurück, wenn eine leere Zeichenfolge (" ") in den numeric- oder decimal-Datentyp konvertiert wird."

Hm, keine explizite Erwähnung, daß man auch eine Fehlermeldung erhält, wenn eine leere Zeichenfolge in einen nummerischen Datentyp geringerer Rangfolge als DECIMAL und NUMERIC konvertiert wird.

Worüber man sich nun streiten kann, ist, warum Microsoft gerade die 0 ausgewählt hat oder ob nicht eine Fehlermeldung angebrachter wäre. Ferner mag man sich nun auch darüber streiten, ob es inkonsistent ist, daß

SELECT ISNUMERIC('')
            
----------- 
0

(1 row(s) affected)

zurückgibt, anstelle von 1. Dies überlasse ich dem geneigten Leser. Tatsache ist, daß dieses Verhalten "by design" ist.

Übrigens, funktioniert auch:

SELECT CAST('' AS DATETIME)
                                                       
------------------------------------------------------ 
1900-01-01 00:00:00.000

(1 row(s) affected)

was ja logisch ist, schließlich wird '' ja zu 0 was wiederum zum 01.01.1900 wird. Naja,...

Dieser Eintrag wurde eingetragen von und ist abgelegt unter SQL Server. Tags: , , ,

Noch kein Feedback


Formular wird geladen...