OdbcDataReader calling IsDBNull changes the behaviour of Get methods
-
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.
Again you used nColNumber twice. You should have used nColNumber and nColName. That was your problem. And yeah I don't use GetXXX either. But that wasn't what caused the exception. You tried to get a string from an int DB value or a int form a varchar DB value courtesy of using twice nColNumber.
All the best, Dan
-
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.
Your code changed. When you test things you should change 1 item at a time, however, you have also changed order and type. In your last example, you are calling GetString and GetInt32 on nColNumber which refers to an integer, your code should read:
int nameColumn = odbcDataReader.GetOrdinal(@"name");
int idColumn = odbcDataReader.GetOrdinal(@"iq");
while (odbcDataReader.Read()){
odbcDataReader.IsDBNull(idColumn);
int iqValue= odbcDataReader.GetInt32(idColumn);
string nameValue = odbcDataReader.GetString(nameColumn );
}I just typed it in the post window but you can see how different variable names make it easier to see.
Need custom software developed? I do custom programming based primarily on MS tools with an emphasis on C# development and consulting. I also do Android Programming as I find it a refreshing break from the MS. "And they, since they Were not the one dead, turned to their affairs" -- Robert Frost
-
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
MDL=>Moshu wrote:
string name = dr[0].ToString();
It's already a string, just cast it --
string name = (string) dr[0];
, no need to call a method. -
MDL=>Moshu wrote:
string name = dr[0].ToString();
It's already a string, just cast it --
string name = (string) dr[0];
, no need to call a method. -
True. Is there a performance reason too, or just style? Cause if there is one, I might need to change some lines of code. I've always happily used ToString() on datareader where the element is a text/string. :)
All the best, Dan
There must be at least a small overhead in calling the method.