Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. OdbcDataReader calling IsDBNull changes the behaviour of Get methods

OdbcDataReader calling IsDBNull changes the behaviour of Get methods

Scheduled Pinned Locked Moved C#
question
25 Posts 6 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • _ Offline
    _ Offline
    __John_
    wrote on last edited by
    #1

    Hi, If I do...

    int nColName   = odbcDataReader.GetOrdinal(@"name");
    int nColNumber = odbcDataReader.GetOrdinal(@"iq");
    
    while (odbcDataReader.Read())
    {
        string strName = odbcDataReader.GetString(nColNumber);
        int nNumber = odbcDataReader.GetInt32(nColNumber);
    }
    

    GetString() succeeds. GetInt32() throws an exception... [System.InvalidCastException] = {"Specified cast is not valid."} However if I do...

    int nColName   = odbcDataReader.GetOrdinal(@"name");
    int nColNumber = odbcDataReader.GetOrdinal(@"iq");
    
    while (odbcDataReader.Read())
    {
        odbcDataReader.IsDBNull(nColNumber);
    
        int nNumber = odbcDataReader.GetInt32(nColNumber);
    
        string strNumber = odbcDataReader.GetString(nColNumber);
    
    }
    

    Now GetInt32() succeeds. And GetString() throws an exception... [System.InvalidCastException] = {"Unable to cast object of type 'System.Int32' to type 'System.String'."} FYI: The column in question 'IQ' is of type 'int'. It seems that calling IsDBNull() first, changes the behaviour of the Get methods. Can anyone explain what is going on? Thanks - John.

    K P D E 4 Replies Last reply
    0
    • _ __John_

      Hi, If I do...

      int nColName   = odbcDataReader.GetOrdinal(@"name");
      int nColNumber = odbcDataReader.GetOrdinal(@"iq");
      
      while (odbcDataReader.Read())
      {
          string strName = odbcDataReader.GetString(nColNumber);
          int nNumber = odbcDataReader.GetInt32(nColNumber);
      }
      

      GetString() succeeds. GetInt32() throws an exception... [System.InvalidCastException] = {"Specified cast is not valid."} However if I do...

      int nColName   = odbcDataReader.GetOrdinal(@"name");
      int nColNumber = odbcDataReader.GetOrdinal(@"iq");
      
      while (odbcDataReader.Read())
      {
          odbcDataReader.IsDBNull(nColNumber);
      
          int nNumber = odbcDataReader.GetInt32(nColNumber);
      
          string strNumber = odbcDataReader.GetString(nColNumber);
      
      }
      

      Now GetInt32() succeeds. And GetString() throws an exception... [System.InvalidCastException] = {"Unable to cast object of type 'System.Int32' to type 'System.String'."} FYI: The column in question 'IQ' is of type 'int'. It seems that calling IsDBNull() first, changes the behaviour of the Get methods. Can anyone explain what is going on? Thanks - John.

      K Offline
      K Offline
      kevinnicol
      wrote on last edited by
      #2

      My only guess at this point is in the first test you are calling GetString first, and in the second test you are calling GetInt32 first. It's possible the the reader is casting your value to what you asked for first?

      _ 1 Reply Last reply
      0
      • _ __John_

        Hi, If I do...

        int nColName   = odbcDataReader.GetOrdinal(@"name");
        int nColNumber = odbcDataReader.GetOrdinal(@"iq");
        
        while (odbcDataReader.Read())
        {
            string strName = odbcDataReader.GetString(nColNumber);
            int nNumber = odbcDataReader.GetInt32(nColNumber);
        }
        

        GetString() succeeds. GetInt32() throws an exception... [System.InvalidCastException] = {"Specified cast is not valid."} However if I do...

        int nColName   = odbcDataReader.GetOrdinal(@"name");
        int nColNumber = odbcDataReader.GetOrdinal(@"iq");
        
        while (odbcDataReader.Read())
        {
            odbcDataReader.IsDBNull(nColNumber);
        
            int nNumber = odbcDataReader.GetInt32(nColNumber);
        
            string strNumber = odbcDataReader.GetString(nColNumber);
        
        }
        

        Now GetInt32() succeeds. And GetString() throws an exception... [System.InvalidCastException] = {"Unable to cast object of type 'System.Int32' to type 'System.String'."} FYI: The column in question 'IQ' is of type 'int'. It seems that calling IsDBNull() first, changes the behaviour of the Get methods. Can anyone explain what is going on? Thanks - John.

        P Offline
        P Offline
        PIEBALDconsult
        wrote on last edited by
        #3

        Well, personally, I never use the Get methods anyway; I just use the indexers.

        __John_ wrote:

        odbcDataReader.IsDBNull(nColNumber);

        Shouldn't you be testing the result?

        1 Reply Last reply
        0
        • K kevinnicol

          My only guess at this point is in the first test you are calling GetString first, and in the second test you are calling GetInt32 first. It's possible the the reader is casting your value to what you asked for first?

          _ Offline
          _ Offline
          __John_
          wrote on last edited by
          #4

          Hi kevinnicol, The only reason for putting them in a different order is because I put the call that throws the exception last. Changing the order just means that you never get to second call because the first throws an exception. @PIEBALDconsult: Yes, I should check the return but it makes no differance to my question.

          D 1 Reply Last reply
          0
          • _ __John_

            Hi kevinnicol, The only reason for putting them in a different order is because I put the call that throws the exception last. Changing the order just means that you never get to second call because the first throws an exception. @PIEBALDconsult: Yes, I should check the return but it makes no differance to my question.

            D Offline
            D Offline
            Dan Mos
            wrote on last edited by
            #5

            Shouldn't it be like:

            while (odbcDataReader.Read())
            {
            string strName = odbcDataReader.GetString(nColNumbernColName);
            int nNumber = odbcDataReader.GetInt32(nColNumber);
            }

            __John_ wrote:

            @PIEBALDconsult: Yes, I should check the return but it makes no differance to my question.

            I beg to differ. If it's true e.g. the value is null it will throw an exception on the int part. Ints can't be null. Either use a nullable int? or check for null first.

            All the best, Dan

            _ 1 Reply Last reply
            0
            • D Dan Mos

              Shouldn't it be like:

              while (odbcDataReader.Read())
              {
              string strName = odbcDataReader.GetString(nColNumbernColName);
              int nNumber = odbcDataReader.GetInt32(nColNumber);
              }

              __John_ wrote:

              @PIEBALDconsult: Yes, I should check the return but it makes no differance to my question.

              I beg to differ. If it's true e.g. the value is null it will throw an exception on the int part. Ints can't be null. Either use a nullable int? or check for null first.

              All the best, Dan

              _ Offline
              _ Offline
              __John_
              wrote on last edited by
              #6

              Non of the returns are null so checking makes no fifferance.

              D 1 Reply Last reply
              0
              • _ __John_

                Non of the returns are null so checking makes no fifferance.

                D Offline
                D Offline
                Dan Mos
                wrote on last edited by
                #7

                Then yes. But you failed to specify that. Honestly I'm out of ideas. Maybe a stupid question like "what is the DB type?" is all I got left. Maybe it should be long or short or... on the C# side. :)

                All the best, Dan

                _ 1 Reply Last reply
                0
                • _ __John_

                  Hi, If I do...

                  int nColName   = odbcDataReader.GetOrdinal(@"name");
                  int nColNumber = odbcDataReader.GetOrdinal(@"iq");
                  
                  while (odbcDataReader.Read())
                  {
                      string strName = odbcDataReader.GetString(nColNumber);
                      int nNumber = odbcDataReader.GetInt32(nColNumber);
                  }
                  

                  GetString() succeeds. GetInt32() throws an exception... [System.InvalidCastException] = {"Specified cast is not valid."} However if I do...

                  int nColName   = odbcDataReader.GetOrdinal(@"name");
                  int nColNumber = odbcDataReader.GetOrdinal(@"iq");
                  
                  while (odbcDataReader.Read())
                  {
                      odbcDataReader.IsDBNull(nColNumber);
                  
                      int nNumber = odbcDataReader.GetInt32(nColNumber);
                  
                      string strNumber = odbcDataReader.GetString(nColNumber);
                  
                  }
                  

                  Now GetInt32() succeeds. And GetString() throws an exception... [System.InvalidCastException] = {"Unable to cast object of type 'System.Int32' to type 'System.String'."} FYI: The column in question 'IQ' is of type 'int'. It seems that calling IsDBNull() first, changes the behaviour of the Get methods. Can anyone explain what is going on? Thanks - John.

                  D Offline
                  D Offline
                  Dan Mos
                  wrote on last edited by
                  #8

                  What is the query that gets executed on the DB while doing a cmd.ExecuteReader()? Maybe there is something missing/wrong there.

                  All the best, Dan

                  _ 1 Reply Last reply
                  0
                  • D Dan Mos

                    Then yes. But you failed to specify that. Honestly I'm out of ideas. Maybe a stupid question like "what is the DB type?" is all I got left. Maybe it should be long or short or... on the C# side. :)

                    All the best, Dan

                    _ Offline
                    _ Offline
                    __John_
                    wrote on last edited by
                    #9

                    Hi MDL=>Moshu, thanks for the reply. The cast that fails is internal to the Get methods. So for example...

                    var Val = odbcDataReader.GetInt32(nColNumber);

                    Still thows the same exception. I am using the data provider for MS SQL Sever that came with vs2010. SQL Server version is 2008. Thanks - John.

                    D 1 Reply Last reply
                    0
                    • D Dan Mos

                      What is the query that gets executed on the DB while doing a cmd.ExecuteReader()? Maybe there is something missing/wrong there.

                      All the best, Dan

                      _ Offline
                      _ Offline
                      __John_
                      wrote on last edited by
                      #10

                      Hi Moshu, The command that I execute is as follows..

                      odbcSelectCommand.CommandText = @"SELECT name, iq FROM Table_People WHERE iq < 3 ORDER BY iq";

                      I get the 'name' and 'iq' but I am only concurned with 'iq' for now.

                      D 2 Replies Last reply
                      0
                      • _ __John_

                        Hi MDL=>Moshu, thanks for the reply. The cast that fails is internal to the Get methods. So for example...

                        var Val = odbcDataReader.GetInt32(nColNumber);

                        Still thows the same exception. I am using the data provider for MS SQL Sever that came with vs2010. SQL Server version is 2008. Thanks - John.

                        D Offline
                        D Offline
                        Dan Mos
                        wrote on last edited by
                        #11

                        In your statement var Val is the same as int Val cause GetInt32() returns a int on success. var Val = odbcDataReader[nColNumber]; is what you should use. Val will be an object of type Object and you can check for null and do the casting later. This is obviously for debugging purposes. Cause the cast and checking are not necessarily once you figure out the problem.

                        All the best, Dan

                        _ 1 Reply Last reply
                        0
                        • _ __John_

                          Hi Moshu, The command that I execute is as follows..

                          odbcSelectCommand.CommandText = @"SELECT name, iq FROM Table_People WHERE iq < 3 ORDER BY iq";

                          I get the 'name' and 'iq' but I am only concurned with 'iq' for now.

                          D Offline
                          D Offline
                          Dan Mos
                          wrote on last edited by
                          #12

                          OK. Heres what I would do. Run that query in SQLManagementStudio and check the results. Are there any? Or some with a field null or...

                          All the best, Dan

                          _ 1 Reply Last reply
                          0
                          • _ __John_

                            Hi Moshu, The command that I execute is as follows..

                            odbcSelectCommand.CommandText = @"SELECT name, iq FROM Table_People WHERE iq < 3 ORDER BY iq";

                            I get the 'name' and 'iq' but I am only concurned with 'iq' for now.

                            D Offline
                            D Offline
                            Dan Mos
                            wrote on last edited by
                            #13

                            Also since you are not using a Select * statement, I would drop the lines of code that get the ordinals. You know them name is 0 and iq is 1 so in a nutshell:

                             while(dr.Read()){
                             string name = dr\[0\].ToString();
                             int iq = (int)dr\[1\];
                            

                            }

                            All the best, Dan

                            _ P 2 Replies Last reply
                            0
                            • D Dan Mos

                              OK. Heres what I would do. Run that query in SQLManagementStudio and check the results. Are there any? Or some with a field null or...

                              All the best, Dan

                              _ Offline
                              _ Offline
                              __John_
                              wrote on last edited by
                              #14

                              Hi MDL=Moshu, thanks for looking at this. The code now looks like this...

                              int nColName = odbcDataReader.GetOrdinal(@"name");
                              int nColNumber = odbcDataReader.GetOrdinal(@"iq");

                              while (odbcDataReader.Read())
                              {
                                  if(odbcDataReader.IsDBNull(nColNumber))
                                  {
                                      continue;
                                  }
                              
                                  int nNumber = odbcDataReader.GetInt32(nColNumber);
                              
                                  string strNumber = odbcDataReader.GetString(nColNumber);
                              
                              }
                              

                              No nulls are returned and the behaviour is the same ie. with the call to IsDBNull() GetString() fails, and without it, GetInt32() fails.

                              D 1 Reply Last reply
                              0
                              • D Dan Mos

                                Also since you are not using a Select * statement, I would drop the lines of code that get the ordinals. You know them name is 0 and iq is 1 so in a nutshell:

                                 while(dr.Read()){
                                 string name = dr\[0\].ToString();
                                 int iq = (int)dr\[1\];
                                

                                }

                                All the best, Dan

                                _ Offline
                                _ Offline
                                __John_
                                wrote on last edited by
                                #15

                                Thanks dan, But I think my way is more robust and future proof. ie. it will still work even with 'SELECT *'. - John

                                D L 2 Replies Last reply
                                0
                                • _ __John_

                                  Hi MDL=Moshu, thanks for looking at this. The code now looks like this...

                                  int nColName = odbcDataReader.GetOrdinal(@"name");
                                  int nColNumber = odbcDataReader.GetOrdinal(@"iq");

                                  while (odbcDataReader.Read())
                                  {
                                      if(odbcDataReader.IsDBNull(nColNumber))
                                      {
                                          continue;
                                      }
                                  
                                      int nNumber = odbcDataReader.GetInt32(nColNumber);
                                  
                                      string strNumber = odbcDataReader.GetString(nColNumber);
                                  
                                  }
                                  

                                  No nulls are returned and the behaviour is the same ie. with the call to IsDBNull() GetString() fails, and without it, GetInt32() fails.

                                  D Offline
                                  D Offline
                                  Dan Mos
                                  wrote on last edited by
                                  #16

                                  This is my final reply. First check my post below. Second you're using nColNumber for both the name and the iq. That's not right and I pointed it out on my first post to this thread. If for some reason you want a string representation of the number/iq then just use strNumber = nNumber.ToString(); Hope it helps. I'm out of CP for today. Going to program some beers now. :)

                                  All the best, Dan

                                  1 Reply Last reply
                                  0
                                  • _ __John_

                                    Thanks dan, But I think my way is more robust and future proof. ie. it will still work even with 'SELECT *'. - John

                                    D Offline
                                    D Offline
                                    Dan Mos
                                    wrote on last edited by
                                    #17

                                    True. Then use dr["name"] and dr["iq"] and it will be future proof.

                                    All the best, Dan

                                    _ 1 Reply Last reply
                                    0
                                    • D Dan Mos

                                      In your statement var Val is the same as int Val cause GetInt32() returns a int on success. var Val = odbcDataReader[nColNumber]; is what you should use. Val will be an object of type Object and you can check for null and do the casting later. This is obviously for debugging purposes. Cause the cast and checking are not necessarily once you figure out the problem.

                                      All the best, Dan

                                      _ Offline
                                      _ Offline
                                      __John_
                                      wrote on last edited by
                                      #18

                                      Hi Dan, Using the indexer, casting to an int always works and casting to a string always fails (invalid cast). So the behavour is predictable and my problem 'kind of' goes away. So for now I will use the indexer and not use the Get???? methods. @PIEBALDconsult: You mentioned indexers earlier but I was not sure what you were getting at. Turns out you were on to something. Thanks.

                                      D 1 Reply Last reply
                                      0
                                      • D Dan Mos

                                        True. Then use dr["name"] and dr["iq"] and it will be future proof.

                                        All the best, Dan

                                        _ Offline
                                        _ Offline
                                        __John_
                                        wrote on last edited by
                                        #19

                                        Hi MDL=>Moshu, Using an indexer as you sagest (with column name) is fine if you only have a small number of fields, but if the number of fields is higher then I think you will take a performance hit.

                                        1 Reply Last reply
                                        0
                                        • _ __John_

                                          Thanks dan, But I think my way is more robust and future proof. ie. it will still work even with 'SELECT *'. - John

                                          L Offline
                                          L Offline
                                          Luc Pattyn
                                          wrote on last edited by
                                          #20

                                          __John_ wrote:

                                          my way is more robust

                                          That doesn't sound very convincing as your code does not produce the expected results to begin with. Have you already figured nColNumber is appearing too many times in your code? (courtesy MDL) :omg:

                                          Luc Pattyn [My Articles] Nil Volentibus Arduum

                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups