SQL 查询因空结果而失败
Posted
技术标签:
【中文标题】SQL 查询因空结果而失败【英文标题】:SQL Query fails on empty result 【发布时间】:2013-09-16 21:16:43 【问题描述】:我有一个使用 ADO 连接对 SQL 数据库执行查询的函数,它只是为数据库条目提供单个结果,该数据库条目只能与 SELECT
类型的查询匹配(即获取我是来自 ID 45 的 x 值,其中只有一个 ID 45 条目)。
该函数工作正常,直到我遇到一个不返回结果的查询。查询只是挂起,应用程序无法继续。这是一个示例查询字符串:
'SELECT Cost FROM MaterialCost ' +
'WHERE MaterialType = ''' + 'MS' +
''' AND Thickness = ''' + '0.250' + '''';
再一次,这个确切的字符串可以正常工作,直到我可能查询我事先知道不存在的东西,它应该返回 null 或空字符串。这是函数:
function SelectOneQuery(AQueryString : String; AADOConnectionString : String) : String;
var
ADOQuery: TADOQuery;
begin
//Create empty ADO Query, then connect to connection string
ADOQuery := TADOQuery.Create(nil);
ADOQuery.ConnectionString:=AADOConnectionString;
ADOQuery.SQL.Clear;
ADOQuery.SQL.Add(AQueryString);
ADOQuery.ExecSQL;
ADOQuery.Open;
//Set first query result and return first result
ADOQuery.First;
if(ADOQuery.Fields.Count > 0) then begin
result:=ADOQuery.Fields[0].Value;
end
else begin
result := '';
end;
end;
我添加了字段计数,但我不确定这是否有帮助。基本上,如果没有结果,我想要result := ''
【问题讨论】:
您为什么不知道添加是否有帮助?程序在添加之前挂在哪里,现在挂在哪里?使用您的调试器来识别哪一行代码。 【参考方案1】:你的代码 sn-p 有几个问题:
主要问题是您正在检查FieldCount
。 FieldCount
将始终为非零,因为它包含查询返回的列数,无论您的查询是否返回记录。一种选择是检查RecordCount
,它表示返回的行数,但更好的选择是检查 EOF
标志。
您正在泄漏 ADOQuery。始终使用 try/finally
块来创建和清理对象。
ExecSQL
用于不返回记录集的查询(如 INSERT 和 DELETE),
请改用Open
无需在Open
之后使用First
如果您一遍又一遍地使用相同的查询,则最好使用参数,作为奖励,您的代码将更具可读性。
例子:
ADOQuery.SQL.Text := 'SELECT Cost FROM MaterialCost WHERE MaterialType = :MaterialType AND Thickness = :Thickness';
ADOQuery.Parameters.ParamByname('MaterialType').Value := 'MS';
ADOQuery.Parameters.ParamByname('Thickness').Value := 0.25;
你的函数代码应该是这样的:
function SelectOneQuery(const AQueryString, AADOConnectionString: string): string;
var
ADOQuery: TADOQuery;
begin
Result := '';
ADOQuery := TADOQuery.Create(nil);
try
ADOQuery.ConnectionString := AADOConnectionString;
ADOQuery.SQL.Text := AQueryString;
ADOQuery.Open;
if not ADOQuery.EOF then
Result := ADOQuery.Fields[0].AsString;
finally
ADOQuery.Free;
end;
end;
【讨论】:
这个答案相当“分散”。对 OPs 问题的确切修复是用对RecordCount <> 0
(== not EOF
,rows)的正确检查来替换对 FieldCount <> 0
(列,什么?)的荒谬检查。
@TLama,我的意思是:OP 将 RecordCount
与 FieldCount
混淆,因此存在错误,请查看原始代码 sn-p。
对于@ikathegreat:仅供参考:TDataSet.Eof documentation。请特别注意列表中的第二项,以及靠近底部的“提示”。
@FreeConsulting:我不使用 Recordcount 的原因是因为访问 Recordcount 会导致在某些情况下获取所有记录,有时这是不希望的。
我个人建议使用 EOF 或 DataSet.IsEmpty 函数,因为某些 DB 在返回 RecordCount 时存在问题。我之前在生产代码中遇到过一个奇怪的问题,即 RecordCount 0 在空数据集上。以上是关于SQL 查询因空结果而失败的主要内容,如果未能解决你的问题,请参考以下文章
SQL中=null查询不出结果而is null可以查询结果说明