SQL没有找到结果

Posted

技术标签:

【中文标题】SQL没有找到结果【英文标题】:SQL not finding results 【发布时间】:2014-01-26 01:02:00 【问题描述】:

此查询当前没有返回任何结果,它应该返回。你能看出这个查询有什么问题吗

字段标题为 NEED_2_TARGET、ID 和 CARD

NEED_2_TARGET = 整数

卡片 = 字符串

ID = 整数

名字的值是'Ash Imp'

this will check if a second target is needed
//**************************************************************************
function TFGame.checkIf2ndTargetIsNeeded(name: string):integer;
//**************************************************************************
var
  targetType : integer; //1 is TCard , 2 is TMana , 0 is no second target needed.
begin
    TargetType := 0;
    Result := targetType;
       with adoquery2 do
        begin
          close;
          sql.Clear;
          sql.Add('SELECT * FROM Spells WHERE CARD = '''+name+''' and NEED_2_TARGET = 1');
          open;
        end;

        if adoquery2.RecordCount < 1 then
          Result := 0
       else
         begin
           Adoquery2.First;
           TargetType := adoquery2.FieldByName(FIELD_TARGET_TYPE).AsInteger;
           result := TargetType;
         end;

end;

sql db 如下所示

ID  CARD    TRIGGER_NUMBER  CATEGORY_NUMBER QUANTITY    TARGET_NUMBER   TYPE_NUMBER PLUS_NUMBER PERCENT STAT_TARGET_NUMBER  REPLACEMENT_CARD_NUMBER MAX_RANDOM  LIFE_TO_ADD REPLACED_DAMAGE NEED_2_TARGET   TYPE_OF_TARGET
27  Ash Imp     2                   2          15             14                                                                                                                                  1             1

【问题讨论】:

显示你的数据来证明你的假设。 请编辑您的问题以提供应该匹配但不匹配的数据。此外,如果您使用参数化查询,它们的执行速度会更快(它们只编译一次),并且您可以消除所有 "'+name+'" 垃圾。您也不应该在没有SQL.Clear 的情况下首先使用SQL.Add,如果您使用的是单个语句,则可以使用SQL.Text 将整个SQL 语句替换为一行代码。 Add 附加到现有 SQL 的末尾,这意味着您可能没有按照您的想法执行。 我知道它没有返回任何结果,因为我跟踪扔了它,当我到达 if adoquery2.RecordCount &lt; 1 then Result := 0 它给我结果 0 这看起来不像“字段是 NEED_2_TARGET、ID 和 CARD”,以及您对 Gordon 的回复(他说“比较 时访问区分大小写”)是“数据库中的所有字段都是大写” - “Ash Imp”对我来说似乎不是全部大写。话虽如此,根据您提供的信息,我认为您的查询没有任何问题(假设现在是准确的)。 @GordonLinoff re:“比较值时访问区分大小写” - 不,不是。看here。 【参考方案1】:

有很多事情可能会出错。

在您的故障排除中,首先也是最重要的是获取您的查询并直接针对您的数据库运行它。 IE。首先通过消除其他事情出错的可能性来确认您的查询是正确的。确认工作的事情越多,分散您解决问题的“噪音”就越少。

    正如其他人所指出的,如果您不清除 SQL 语句,您可能会在 first 结果集中返回零行。 是的,我知道,您已经评论说您正在清除您之前的查询。关键是:如果您在解决问题时遇到困难,您如何确定问题出在哪里?所以,不要遗漏可能相关的信息! 这巧妙地将我们带到了第二种可能性。我看不到您的其余代码,所以我不得不问:您是否在更改查询后刷新数据?如果您没有CloseOpen 您的查询,您可能正在查看先前执行的结果集。 我不确定您是否可以在组件为Active 时更改查询文本,或者甚至不确定这是否取决于您正在使用的数据访问组件。关键是,值得检查。 您的应用程序是否连接到正确的数据库?由于您使用的是 Access,因此很容易在没有意识到的情况下连接到不同的数据库文件。 您可以通过更改查询以返回所有行来检查这一点(即删除 WHERE 子句)。 您希望更改 SQL 查询中使用的引号。而不是:...CARD = "'+name+'" ORDER... 而不是使用...CARD = '''+name+''' ORDER... 据我所知,单引号是 ANSI 标准。即使某些数据库允许双引号,但使用它们会限制可移植性,并且在通过某些数据访问驱动程序传递时可能会产生意外结果。 检查CARD 列的数据类型。如果它是一个固定长度的字符串,那么数据值将被填充。例如。如果CARDchar(10),那么您实际上可能需要寻找'Ash Imp '。 同样,实际值可能在单词之前/之后包含空格。使用不带 WHERE 的 select 并检查列的实际值。您还可以检查SELECT * FROM Spells WHERE CARD LIKE '%Ash Imp%' 是否有效。

最后,正如其他人所建议的,您最好使用参数化查询,而不是自己动态构建查询。

您的代码将更具可读性和灵活性。 你可以让你的代码强类型;因此避免将数字和日期等内容转换为字符串。 您无需担心日期格式的特殊性。 您消除了一些安全问题。

【讨论】:

好的,我已经尝试使用 ' 并且仍然没有好处.. 但如果我使用 sql.Add('SELECT * FROM Spells'); 它确实会找到记录。是的,我有Close sql.clear sql.add Open 还有其他建议吗? @GlenMorse 我添加了一个我第一次忘记包含的选项。另外,您是否直接在数据库上运行查询以确认没有其他问题。使用SELECT * FROM Spells 是一种类似的消除技术,但并不完全相同。因此,直接在数据库上运行您的预期查询仍然很重要。【参考方案2】:

@GordonLinoff db 中的所有字段都是大写

如果这是真的,那是你的问题。 SQL 通常对字符/字符串值进行区分大小写的比较,除非您告诉它不要这样做,例如 STRCMP() (mysql 4+)、LOWER()UPPER() (SQLServer、Firebird) 等。我也会尽可能将条件括在括号中:

sql.Text := 'SELECT * FROM Spells WHERE (NEED_2_TARGET = 1) AND (STRCMP(CARD, "'+name+'") = 0) ORDER by ID';

sql.Text := 'SELECT * FROM Spells WHERE (NEED_2_TARGET = 1) AND (LOWER(CARD) = "'+LowerCase(name)+'") ORDER by ID';

sql.Text := 'SELECT * FROM Spells WHERE (NEED_2_TARGET = 1) AND (UPPER(CARD) = "'+UpperCase(name)+'") ORDER by ID';

【讨论】:

除非那不是真的,根据他发布的数据和name中的值。 name 和列的内容都不是大写的。 我确实说过“如果那是真的”:) 我知道。我没有投反对票。 :-) 只是指出张贴者已经在这里对事实进行了几次失实陈述,包括发布的数据清楚地表明事实并非如此。 @GlenMorse:“Ash Imp”,卡片栏。 (Gordon 引用了“比较值”,意思是“匹配内容”,您回答“db 中的所有字段都是大写”。 cc: @CraigYoung - 当 Gordon Linoff 说“比较值时访问区分大小写”时,他是不正确的。看here。【参考方案3】:

这是或曾经是一个问题

With Adoquery2 do
begin
...
end

在 sql 中使用 name 时,实际上得到的是 adoquery2.name 而不是 var 名称。我通过将name 更改为Cname 解决了这个问题,之后就没有问题了。

【讨论】:

with 又来了!使用 eval 工具提示而不是 Name,您无法轻易注意到问题,这使情况变得更糟 - 因为那不起作用! @GlenMorse 您刚刚从 with 声明中遭受了第一口。我强烈建议您宁愿完全消除 with,否则您将来可能会遇到更多糟糕的体验。关键是 with 总是可以很容易地更改为局部变量别名,因此绝对没有必要让自己承担风险。

以上是关于SQL没有找到结果的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 bigquery sql 没有返回任何结果?

禁用 SQL2008 结果集中的消息

sql left join - 如果没有结果,则返回默认值

sql server怎么导出查询结果为脚本

sql - 有没有办法过滤SELECT查询的结果,使用另一个SELECT查询?

OUTER JOIN 结果缺少行,没有 WHERE 子句(找到解决方法)