在查询中处理不需要的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)"吗?或。。。???

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

(回答关于在客户端处理事情的附加问题...

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# 中,nullDBNull 是不同的小动物。

编辑

同样,对于数字数据库字段(例如,类型 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。 此外,使用 LEFTRIGHT 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获得