在查询中处理不需要的MS Access文本字段的最安全实用方法是什么
本文关键字:安全 是什么 方法 字段 Access 查询 处理 不需要 MS 文本 | 更新日期: 2023-09-27 18:36:50
在查询MS Access时,我了解到(如何抢占"指定的强制转换无效"异常?)我必须通过使用"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
我假设这仅适用于已指定为必需的文本列 == false。我的 AS效率是否错误 - 我必须对所有非必需的列执行此操作吗?
具体来说,如果我需要对数据类型为双精度的列进行防御性查询,这是这样做的方法吗:
IIF(ISNULL(two_bagger),0.0,two_bagger)
?
或者更好的是(人们总是希望):是否有一些更干净/不那么突兀的方法来处理不包含每列数据的结果集?
如果有任何区别,我正在使用OleDbDataReader从.NET 4.5.1 Web API应用程序查询MS Access数据库(新酒皮中的旧抱怨?
更新
回复:HansUp(Reach for the Sky?)的建议:"也许从.Net端攻击它会更有成效,并使代码更适应Nulls",像这样的事情会是这样做的方法,还是有更有效/更安全的方法:
if (null == oleDbD8aReader.GetString(2))
{
description = "Blank description";
}
else
{
description = oleDbD8aReader.GetString(2);
}
?
更新 2
我更改了代码以检查 DBNull,当它是 DBNull 时,根据数据类型(string.empty 表示文本,0 表示整数,0.00 表示双精度)将值设置为通用值,但我仍然得到相同的错误消息。
更新 3
我在此行收到"指定的强制转换无效":
long RedemItemId = (oleDbD8aReader["dbp_id"] is DBNull ? 0 : (long)oleDbD8aReader["dbp_id"]);
dbp_id 是访问表中的 LongInt
从查询返回的数据在该列中包含以下值:
5
20
30
40
45
60
70
75
90
120
120
。那么,这些值中的任何一个怎么可能使长期投射失败呢?我应该使用"Convert.ToX()"而不是"(long)"吗?或。。。???
(回答关于在客户端处理事情的附加问题...
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
是不同的小动物。
编辑
同样,对于数字数据库字段(例如,类型 Double
),您可以使用
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"]));
"对于已指定为必需的文本列 == false ...我是否必须对所有非必需的列执行此操作?
也许。 具有其他数据类型(数字、日期/时间等)的列可能包含 Null,前提是尚未为它们设置 Required = True。 此外,使用 LEFT
或 RIGHT JOIN
即使源表中的所有列都具有 Required = True,也可以在不匹配的行中获得 Null。 如果不希望查询输出中出现任何 Null,则必须对所有可能的情况进行替换。
"关于数据类型为双精度的列,这是这样做的方法吗"
IIF(ISNULL(two_bagger),0.0,two_bagger)
是的,这应该有效。 或者,如果您愿意,可以这样做...
IIF(two_bagger Is Null,0.0,two_bagger)
从 OleDB 来看,我不相信有"一些更干净/不那么突兀的方式来处理不包含每列数据的结果集"。 也许从.Net
端攻击这一点并使代码更适应 Null 会更有成效......那么,您无需要求数据库引擎用其他内容替换 Null。
有一个非SQL非Jet但访问函数NZ可以提供帮助
IIF(ISNULL(description),'',description)
几乎等于
nz(description,'')
检查它是否可以通过oleDbReader获得