在查询中处理非必需的MS Access文本字段最安全的实用方法是什么?

时间:2013-10-25 15:46:06

标签: c# sql ms-access isnull oledbdatareader

在查询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);
}

更新2

我更改了代码以检查DBNull,根据数据类型(text为string.empty,int为0,双精度为0.00)将值设置为泛型,当它为DBNull时,我仍然得到相同的值错误的消息。

更新3

我在这一行收到“指定的演员表无效”:

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)”吗?或... ???

3 个答案:

答案 0 :(得分:2)

“对于已指定为必需的文本列== false ...我是否必须对所有非必需列执行此操作?”

也许。如果您没有为其设置Required = True,则具有其他数据类型(数字,日期/时间等)的列可以包含Null。此外,使用LEFTRIGHT 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#中,nullDBNulldifferent 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检查它是否可用