在查询MS Access时,我已经学会了(How can I preempt a "Specified cast is not valid" exception?)我必须通过使用“”来防御性地查询Text(字符串)值可能为空(或者显然,实际上为null) IIF(ISNULL(colName),'',colName)“构造,例如:
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
我认为只有指定required == false的Text列才需要这样做。我的假设是错误的 - 我是否必须对所有不需要的列进行此操作?
具体来说,如果我需要以防御方式查询数据类型为double的列,这是否可以这样做:
IIF(ISNULL(two_bagger),0.0,two_bagger)
或者更好(一个人总是希望):是否有一些更清晰/更少突兀的方法来处理每列中不包含数据的结果集?
如果它有任何区别,我使用OleDbDataReader从旧的4.5.1 Web API应用程序查询MS Access数据库(在新的winekins中发出旧的声音?)
Re:HansUp(伸手可及的天空?)建议:“从.Net那边攻击这个并使代码更容易接受Nulls 会更高效”,就像这样这是做到这一点的方式,还是有更有效/更安全的方式:
if (null == oleDbD8aReader.GetString(2))
{
description = "Blank description";
}
else
{
description = oleDbD8aReader.GetString(2);
}
我更改了代码以检查DBNull,根据数据类型(text为string.empty,int为0,双精度为0.00)将值设置为泛型,当它为DBNull时,我仍然得到相同的值错误的消息。
我在这一行收到“指定的演员表无效”:
long RedemItemId = (oleDbD8aReader["dbp_id"] is DBNull ? 0 : (long)oleDbD8aReader["dbp_id"]);
dbp_id是Access表中的LongInt
从查询返回的数据包括该列中的这些值:
5
20
30
40
45
60
70
75
90
120
120
...那么这些价值观中的任何一个如何能够使演员阵容变得漫长?我应该使用“Convert.ToX()”而不是“(long)”吗?或... ???
答案 0 :(得分:2)
“对于已指定为必需的文本列== false ...我是否必须对所有非必需列执行此操作?”
也许。如果您没有为其设置Required = True,则具有其他数据类型(数字,日期/时间等)的列可以包含Null。此外,使用LEFT
或RIGHT JOIN
,即使源表中的所有列都具有Required = True,您也可以在不匹配的行中获得Null。如果您不想在查询输出中使用任何Null,则必须对所有可能的情况进行替换。
“关于数据类型为double的列,这是做到这一点的方法”
IIF(ISNULL(two_bagger),0.0,two_bagger)
是的,这应该有效。或者你可以这样做,如果你更喜欢......
IIF(two_bagger Is Null,0.0,two_bagger)
从OleDb,我不相信有“一些更清洁/不那么突兀的方式来处理每列中不包含数据的结果集”。也许从.Net
方面攻击它并使代码更适应Nulls会更有效率......那么你就不需要让db引擎用其他东西代替Nulls。
答案 1 :(得分:2)
(回应关于在客户端处理事情的附加问题......)
OleDbDataReader
会将Access数据库Text
字段作为System.String
(如果包含值)或System.DBNull
(如果它是Null
返回数据库)。
因此,如果您想将DBNull
值转换为空(零长度)字符串,请使用
cmd.CommandText =
"SELECT txtCol FROM Clients WHERE ID = 3";
OleDbDataReader rdr = cmd.ExecuteReader();
rdr.Read();
string result = rdr["txtCol"].toString();
如果你做关心,如果返回的值是DBNull
,那么测试它
cmd.CommandText =
"SELECT txtCol FROM Clients WHERE ID = 3";
OleDbDataReader rdr = cmd.ExecuteReader();
rdr.Read();
string result;
if (rdr["txtCol"] is DBNull)
{
result = "{That field was Null.}";
}
else
{
result = rdr["txtCol"].ToString();
}
(请注意,在C#中,null
和DBNull
为different critters。)
同样,对于数字数据库字段(例如,类型为Double
),您可以强制使用#34;使用
cmd.CommandText =
"SELECT dblCol FROM Clients WHERE ID = 3";
OleDbDataReader rdr = cmd.ExecuteReader();
rdr.Read();
double dResult = (rdr["dblCol"] is DBNull ? 0 : Convert.ToDouble(rdr["dblCol"]));
答案 2 :(得分:0)
有一个非SQL非Jet但Access函数NZ可以提供帮助
IIF(ISNULL(description),'',description)
几乎等于
nz(description,'')
通过oleDbReader检查它是否可用