In querying MS Access, I've learned (How can I preempt a "Specified cast is not valid" exception?) that I have to query defensively where Text (string) values may be empty (or, apparently, in actuality null) by using the "IIF(ISNULL(colName),'',colName)" construct, such as:
SELECT id, pack_size, IIF(ISNULL(description),'',description), department, subdepartment, IIF(ISNULL(vendor_id),'',vendor_id), IIF(ISNULL(vendor_item),'',vendor_item), avg_cost, list_cost FROM PhunkyPlatypi ORDER BY id
I assume that this is only necessary for Text columns that have been designated required == false. Is my ASSumption wrong - do I have to do this with all non-required columns?
Specifically, if I need to query defensively regarding columns of data type double, is this the way to do that:
IIF(ISNULL(two_bagger),0.0,two_bagger)
?
Or better yet (one can always hope): Is there some cleaner/less obtrusive way of dealing with result sets that do not contain data in every column?
If it makes any difference, I'm querying the MS Access database from a .NET 4.5.1 Web API app using OleDbDataReader (old whine in new wineskins?)
UPDATE
Re: HansUp's (Reach for the Sky?) suggestion: "Maybe it would be more productive to attack this from the .Net side and make the code more accommodating of Nulls", would something like this be the way to do it, or is there a more efficient/safer way:
if (null == oleDbD8aReader.GetString(2))
{
description = "Blank description";
}
else
{
description = oleDbD8aReader.GetString(2);
}
?
UPDATE 2
I changed the code to check for DBNull, setting the value to a generic one based on the data type (string.empty for Text, 0 for ints, 0.00 for double) when it IS DBNull, but I still get the same err msg.
UPDATE 3
I'm getting "Specified cast is invalid" on this line:
long RedemItemId = (oleDbD8aReader["dbp_id"] is DBNull ? 0 : (long)oleDbD8aReader["dbp_id"]);
dbp_id is a LongInt in the Access table
The data being returned from the query includes these values in that column:
5
20
30
40
45
60
70
75
90
120
120
...so how could any of these values be failling a cast to long? Should I be using "Convert.ToX()" instead of "(long)"? Or...???