Null data not handled properly

RogerSchlueter-7899 1,801 Reputation points
2026-09-13T16:06:35.95+00:00

I am reading data from a SQL Server database with this code:

Dim rdr As SqlDataReader = cmd.ExecuteReader
While rdr.Read()
	evnt = New MyEvent With
		{
		.EventID = If(IsDBNull(rdr.GetInt32("EventID")), Nothing, rdr.GetInt32("EventID")),
		....
		.LastUpdate = rdr.GetDateTime("LastUpdate"),
		.OrganizerID = If(IsDBNull(rdr.GetInt32("OrganizerID")), Nothing, rdr.GetInt32("OrganizerID")),
		....
		}

This fails with this message:

System.Data.SqlTypes.SqlNullValueException HResult=0x80131931 Message=Data is Null. This method or property cannot be called on Null values.

If I remove the line that reads the OrganizerID column, all of the data are read correctly so that is the source of the problem. But my code is supposed to handle that null case. If I temporarily set OrganizerID=1 in the underlying tables, the data are read properly. Searching on the error message provides no useful information.

I don't know how to fix this problem.

Developer technologies | VB
0 comments No comments

Answer accepted by question author
Gatlin Le (WICLOUD CORPORATION) 320 Reputation points Microsoft External Staff Moderator
2026-09-14T04:00:26.2433333+00:00

Hi @RogerSchlueter-7899 ,

Thank you for sharing the details. As Erland Sommarskog correctly pointed out, the key issue is that IsDBNull expects the zero-based ordinal of the column, rather than a value already retrieved from the database.

In the original expression:

IsDBNull(rdr.GetInt32("OrganizerID"))

GetInt32 is evaluated first. If OrganizerID contains SQL NULL, the exception is raised before IsDBNull can perform the check.

You can retrieve the column ordinal first, check whether the column contains DBNull, and only then call GetInt32:

Dim organizerOrdinal As Integer = rdr.GetOrdinal("OrganizerID")

.OrganizerID =
    If(rdr.IsDBNull(organizerOrdinal),
       CType(Nothing, Integer?),
       CType(rdr.GetInt32(organizerOrdinal), Integer?))

The property should also be nullable if it needs to represent a database NULL:

Public Property OrganizerID As Integer?

The same pattern should be applied to any other database columns that may contain NULL. For example:

Dim eventIdOrdinal As Integer = rdr.GetOrdinal("EventID")
Dim lastUpdateOrdinal As Integer = rdr.GetOrdinal("LastUpdate")
Dim organizerOrdinal As Integer = rdr.GetOrdinal("OrganizerID")

While rdr.Read()
    evnt = New MyEvent With {
        .EventID =
            If(rdr.IsDBNull(eventIdOrdinal),
               CType(Nothing, Integer?),
               CType(rdr.GetInt32(eventIdOrdinal), Integer?)),
        .LastUpdate =
            If(rdr.IsDBNull(lastUpdateOrdinal),
               CType(Nothing, DateTime?),
               CType(rdr.GetDateTime(lastUpdateOrdinal), DateTime?)),
        .OrganizerID =
            If(rdr.IsDBNull(organizerOrdinal),
               CType(Nothing, Integer?),
               CType(rdr.GetInt32(organizerOrdinal), Integer?))
    }
End While

Microsoft's SqlDataReader.IsDBNull(Int32) documentation confirms that the parameter is the zero-based column ordinal and recommends calling IsDBNull before typed getters to avoid an exception.

Please try this pattern and let me know whether the exception is resolved. If you found my response helpful or informative, I would greatly appreciate it if you could share your thoughts by reacting to this answer or leaving a comment.

Thank you.

Was this answer helpful?

1 person found this answer helpful.

2 additional answers

Sort by: Most helpful
  1. Erland Sommarskog 137.4K Reputation points MVP Volunteer Moderator
    2026-09-13T16:59:02.03+00:00

    I was first thinking "what is the AI smoking?", but reading the documentation brought me the missing piece in the puzzle:

    User's image

    That is, you don't feed IsDBNull a value returned from the database, but the ordinal for the column you want to investigate. Maybe you can even feed it the name directly, like you do with GetXxxx methods. (I don't write data-access code that often. My speciality is on the SQL Server side.)

    Was this answer helpful?


  2. AI answer

    2026-09-13T16:06:48.51+00:00

    IsDBNull(rdr.GetInt32("OrganizerID")) fails before IsDBNull can help, because GetInt32 is already trying to read the column as a non-null Int32. When the database value is NULL, that call throws SqlNullValueException.

    Use a null check on the column value first, and only call GetInt32 when the value is not null.

    In ADO.NET, database nulls are not the same as CLR nullable value types. For database ANSI SQL nulls, null handling must be done explicitly.

    A correct pattern is:

    While rdr.Read()
        evnt = New MyEvent With {
            .EventID = If(rdr.IsDBNull(rdr.GetOrdinal("EventID")), Nothing, rdr.GetInt32(rdr.GetOrdinal("EventID"))),
            .LastUpdate = rdr.GetDateTime(rdr.GetOrdinal("LastUpdate")),
            .OrganizerID = If(rdr.IsDBNull(rdr.GetOrdinal("OrganizerID")), Nothing, rdr.GetInt32(rdr.GetOrdinal("OrganizerID")))
        }
    End While
    

    Key points:

    • NULL in SQL Server is an unknown or missing value.
    • A null is not 0 and not an empty string.
    • Comparisons and expressions involving null follow SQL three-valued logic.
    • For database values, check for null before calling typed getters like GetInt32 or GetDateTime.

    Also verify that the target property can actually hold null:

    Public Property OrganizerID As Integer?
    

    If OrganizerID is declared as plain Integer, assigning Nothing will not represent a database null in the way intended.

    The same rule applies to any nullable database column, including LastUpdate if that column can also contain NULL.


    AI-generated content may be incorrect. Read our transparency notes for more information.

    Was this answer helpful?

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.