SQL-Server: Uniqueidentifier is NULL

Manchmal sucht man ewig nach einer Lösung für ein Problem, welches man nicht lösen kann. Nein, ich hab mich nicht an der Quadratur des Kreises versucht. Ganz was triviales. Eine SQL Abfrage in C#: Zähle alle Eintrag einer Tabelle wo ein bestimmtes Feld (Typ Uniqueidentifier) NULL ist.

Vorbereitung

Machen wir uns mal eine Tabelle, die eine Spalte mit dem Typ ‚Uniqueidentifier‘ enthält und füllen diese mit einigen Werten. Da das Feld kein Pflichtfeld ist, packen wir auch ein paar ‚NULL‘ Werte rein.

CREATE TABLE SampleTable(id INT IDENTITY, uid uniqueidentifier NULL)
 
INSERT INTO SampleTable(uid) VALUES (newid()), (newid()), (newid()), (NULL), (newid()), (NULL), (newid())

Startet man nun eine normale Abfrage auf diese Tabelle erhält man in etwas folgendes Ergebnis:
(Sollte jemand zufällig dieselben UIDs erhalten wie ich bei diesem Beispiel würde mich das sehr wundern)

SELECT * FROM SampleTable
id uid
1 BE53E63D-CAC1-4AD4-A923-A2FA1364E277
2 0719A96C-91D2-4818-9C4D-962532B841FC
3 F2E6D2DE-2367-4CF3-90AD-C616393348FF
4 NULL
5 84E52D4E-3AA7-4B7C-B9FB-0902A8710B95
6 NULL
7 C99329F3-EDAE-4D36-BF35-9A9241699353

Auch wenn man die Einträge in diesem Fall schneller gezählt hätte, als die Abfragen getippt, wollen wir uns doch mal ansehen, was wir für Werte erhalten

SELECT COUNT(*) FROM SampleTable
SELECT COUNT(*) FROM SampleTable WHERE UID IS NULL
SELECT COUNT(*) FROM SampleTable WHERE UID IS NOT NULL

Es ist nicht verwunderlich, dass wir als Ergebnis die Ziffern 7, 2 und 5 erhalten. (Gegenprobe: 5 + 2 = 7 *phu*)

Das Problem

Schnell mal eine Sample Application in C# erstellt, in der wir wieder unsere Einträge zählen. Zuerst wieder die drei Befehle, wie wir sie von oben kennen.
Da ich gelernt habe mit Parametern zu arbeiten habe ich als viertes Beispiel noch einen Befehl, bei dem wir auf einen bestimmten Wert einschränken. (Sollte also ‚1‘ zurückliefern)
Die fünfte und Abfrage ist eigentlich gleich mit der dritten – nur das ich auch hier Parameter verwende.

Hier der relevante Code-Ausschnitt:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using (SqlConnection connection = new SqlConnection(connectionString))
{
    connection.Open();
 
    using (SqlCommand command = connection.CreateCommand())
    {
        command.CommandType = CommandType.Text;
 
        command.CommandText = "SELECT Count(*) FROM SampleTable";
        object value1 = command.ExecuteScalar();
 
        command.CommandText = "SELECT Count(*) FROM SampleTable WHERE UID is null";
        object value2 = command.ExecuteScalar();
 
        command.CommandText = "SELECT Count(*) FROM SampleTable WHERE UID is not null";
        object value3 = command.ExecuteScalar();
 
        command.CommandText = "SELECT Count(*) FROM SampleTable WHERE UID = @UID";
        command.Parameters.Add(new SqlParameter("@UID", "BE53E63D-CAC1-4AD4-A923-A2FA1364E277"));
        object value4 = command.ExecuteScalar();
 
        command.Parameters.Clear();
        command.CommandText = "SELECT Count(*) FROM SampleTable WHERE UID is @UID";
        command.Parameters.Add(new SqlParameter("@UID", DBNull.Value));
        object value5 = command.ExecuteScalar();
    }
 
   connection.Close();
}

Das Ergebnisse der Abfragen sehen dann wie folgt aus;

Variable Wert
value1 7
value2 5
value3 2
value4 1
value5 0

Alles in Ordnung? Ich glaube nicht. Was ist mit dem fünften Wert? Müsste dieser nicht eigentlich ‚2‘ sein? Ich meine auch.

Ich habe einen Forumseintrag im Internet gefunden in dem es heißt, dass hierbei leider das Statement nicht richtig generiert wird. Laut dem Beitrag wäre Befehl der im fünften Fall an den SQL Server gesendet wird folgender:

 SELECT COUNT(*) FROM SampleTable WHERE UID = NULL

Was wirklich kein Ergebnis liefert (Ist ja auch so nicht korrekt).

Edit: Hier einige Beiträge zu dem Thema:
PCPreview.co.uk
Velocityreviews
ASP.NET Zone

Die Lösung

Parameter nicht verwenden. I’m sorry. Ich habe bisher noch keine andere Lösung gefunden. Falls jemand eine Idee oder einen Hinweis hat – nur her damit.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert