1

I am searching a database and pulling results from it. Before displaying it in WPF I am checking the contents of the text in a field called PrimarySponsor which can be (1) blank/null (2) number at 3rd character (3) persons name. I am currently using Char.IsNumber to check option 2 if there is a number at position 4.

 If reader("PrimarySponsor") Is DBNull.Value Then

                    resultxPrimSpon = ""

                ElseIf Char.IsNumber(reader("PrimarySponsor"), 3) Then

                    resultxPrimSpon = "Terminated"

                Else
                    resultxPrimSpon = reader("PrimarySponsor")

                End If

Before I put the Char.IsNumber check in I was getting 4 results displaying. When i add the Char.IsNumber code I only get 2 results along with the error;

Error while connecting to SQLServer.Sepcified argument was out of the range of valid values. Parameter name: index.

Anyone have any ideas about why this is happening or how to work around it?

Aaron C
  • 135
  • 3
  • 12
  • Its the value of reader("PrimarySponsor") sorry, editing the code above to show that. – Aaron C Jan 11 '16 at 08:55
  • Where comes this error message from: _"Error while connecting to SQLServer..."_ You are using `Char.IsNumber` which is totally unrelated to SQL-Server – Tim Schmelter Jan 11 '16 at 08:56
  • 2
    why are you reading it multiple times ? read it once and cache it ? – Muds Jan 11 '16 at 08:56
  • Im using SQL to pull in results and then reading through them and adding them to a listview. I didn't think the error was in the SQL as when I take out the char.isnumber code the correct results are returned. The query is ran before i run the above code – Aaron C Jan 11 '16 at 08:57
  • @Muds beginner in vb so consider it a rookie mistake, not sure how to cache it – Aaron C Jan 11 '16 at 08:58
  • dim val = reader("PrimarySponsor") .... and then use val everywhere – Muds Jan 11 '16 at 08:59
  • @Muds il update this cheers, still leading to the error tho, any ideas around this? – Aaron C Jan 11 '16 at 09:00
  • 2
    @AaronC: just store the value from the reader if you want to access it more than once(the term cache is misleading). Therefore use a variable of the correct type, for example `String`. – Tim Schmelter Jan 11 '16 at 09:00
  • @TimSchmelter cheers, il give this a go here and see if anything is solved. – Aaron C Jan 11 '16 at 09:02
  • yes cache is misleading – Muds Jan 11 '16 at 09:05
  • @TimSchmelter still getting same error, would there be a different way to search the result to check if it contains integers, the field i am trying to find will consist of aa12345 as in char, char, int int int int. – Aaron C Jan 11 '16 at 09:14
  • @Muds still getting the error any ideas how to fix? – Aaron C Jan 11 '16 at 09:16
  • debug it, it seems its just not 4 chars long – Muds Jan 11 '16 at 09:17
  • @Muds ok il get to this, if it helps, the first two results displayed work, the third result is null and it doesnt get around to displaying the fourth result as it leads to the error. But if i am firstly checking if the value is null in the above code, does it sound logically correct. As in check if its null, if not check if it contains a number, if not output the contents? – Aaron C Jan 11 '16 at 09:22
  • instead of null check do ... `dim val as string = reader("PrimarySponsor").. then if(string.IsNullOrEmpty(val) = false)` – Muds Jan 11 '16 at 09:27

1 Answers1

2

It's not clear where you get that error because Char.IsNumber is not a sql-server method. So i assume that it's a custom message from you. However, the "Specified argument was out of the range" is documented:

ArgumentOutOfRangeException: index is less than zero or greater than the last position in s.

So it seems that at least one of the strings is shorter than 4 characters. In general you should store the reader values in a variable of the correct type if you have to access it more than once. In this case in a String-variable.

But it's also a good idea to create a custom type that has all properties. Then you can add all to a List(Of T). Here's an example:

Public Class Sponsor
    Public Property PrimarySponsor As String
End Class

Of course you could also fill a List(Of String) instead of a List(Of Sponsor). Then you don't need to create a new type. But i assume that you have more than one column in the table. Using a custom type increases readability and maintainability much.

....

Dim allSponsors As New List(Of Sponsor)
Using reader = command.ExecuteReader()
    If reader.HasRows Then
        Dim primSponsorColumnIndex = reader.GetOrdinal("PrimarySponsor")
        While reader.Read
            Dim sponsor As New Sponsor()
            If reader.IsDBNull(primSponsorColumnIndex) Then
                sponsor.PrimarySponsor = ""
            Else
                sponsor.PrimarySponsor = reader.GetString(primSponsorColumnIndex)
                If sponsor.PrimarySponsor.Length >= 4 AndAlso _
                   Char.IsDigit(sponsor.PrimarySponsor(3)) Then
                    sponsor.PrimarySponsor = "Terminated"
                End If
            End If
            allSponsors.Add(sponsor)
        End While
    End If
End Using

First use DataReader.IsDBNull to check if the value is Null. Then check if Length >= 4 before you use Char.IsDigit(sponsor.PrimarySponsor(3)) to avoid the ArgumentOutOfRangeException.

Difference between Char.IsDigit() and Char.IsNumber() in C#

Community
  • 1
  • 1
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939