Home > SQL-Server 2005 > T-SQL CASE und die implizite Datentypkonvertierung

T-SQL CASE und die implizite Datentypkonvertierung

Wenn man in einem Ausdruck einen CASE-Block verwendet, so ist dies auf den ersten Blick noch keine Besonderheit. Vergisst man jedoch dabei, dass SQL Server eine implizite Datentypkonvertierung vornimmt, so kann dies zu fehlerhaften Ergebnissen führen die noch dazu sehr schwer zu finden sind.

Betrachten wir hierfür einmal folgendes Beispiel:

 T-SQL |  copy code |? 
01
DECLARE @AlteKndNr VARCHAR(15)
02
DECLARE @Von       VARCHAR(15)
03
DECLARE @Auf       VARCHAR(15)
04
DECLARE @Regel     INT
05
 
06
SET @AlteKndNr = 'K011110999-VIP'
07
 
08
SET @Regel = 1
09
SET @Von   = CASE @Regel WHEN 1 THEN '099' WHEN 2 THEN '0111' ELSE 0 END
10
SET @Auf   = CASE @Regel WHEN 1 THEN '033' WHEN 2 THEN '0000' ELSE 0 END
11
 
12
SELECT NeueKndNr = REPLACE(@AlteKndNr, @Von, @Auf), @Von, @Auf
13
 
14
SET @Regel = 2
15
SET @Von   = CASE @Regel WHEN 1 THEN '099' WHEN 2 THEN '0111' ELSE 0 END
16
SET @Auf   = CASE @Regel WHEN 1 THEN '033' WHEN 2 THEN '0000' ELSE 0 END
17
 
18
SELECT NeueKndNr = REPLACE(@AlteKndNr, @Von, @Auf), @Von, @Auf
19
 
20
-- -------------------------------------------------------------------------
21
-- Ergebnisse:
22
--
23
-- NeueKdNr bei @Regel = 1: K011110339-VIP = OK
24
-- NeueKdNr bei @Regel = 2: K0010999-VIP   = FALSCH
25
--                          K000010999-VIP = Das währe richtig!
26
-- -------------------------------------------------------------------------
27

Wie man sehen kann wird bei @Regel=2 eine falsche Konvertierung durchgeführt. Dies liegt an der oben besprochenen impliziten Konvertierungsregel von SQL Server. Wenn mehrere Datentypen in einem Ausdruck vorkommen so werden diese in einen Zieldatentyp konvertiert.

Der Typ des Zieldatentyps ist der Typ des Wertes der in folgender Tabelle den höchsten Prioritätswert (1) aufweist.

In unserem Fall wird im CASE-Block in den When-Zweigen ein String zurückgegeben, im Else-Zweig hingegen ein Integerwert! Obwohl der Else-Zweig nicht angesprochen wird, ist der Gesamtdatentyp des CASE-Blocks gem. Konvertierungstabelle ein Integerwert, da dieser die höhere Priorität gegenüber den varchar-Werten der When-Zweige aufweist.

Wenn man also den Else-Zweig des Case-Blocks mit Else ‘0′ definiert (man beachte die Hochkommas), dann wird auch das richtige Ergebnis ausgegeben.

Hier die Tabelle die die Prioritäten bei der impliziten Typkonvertierung aufzeigt:

Datentyp-Prioritäten
Priorität Datentyp
1 Benuter-Definierter Typ
2 sql_variant
3 xml
4 datetime
5 smalldatetime
6 float
7 real
8 decimal
9 money
10 smallmoney
11 bigint
12 int
13 smallint
14 tinyint
15 bit
16 ntext
17 text
18 image
19 timestamp
20 uniqueidentifier
21 nvarchar
22 nchar
23 varchar
24 char
25 varbinary
26 binary

have fun ;)

KategorienSQL-Server 2005