首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SQL查询一致地选择不匹配的行。

问SQL查询一致地选择不匹配的行。
EN

Stack Overflow用户
提问于 2013-09-05 19:19:25
回答 2查看 154关注 0票数 2

我将md5哈希存储在cookie和数据库中。我有一个函数validate_cookie(),它读取这个cookie并查询数据库以找到与此哈希关联的用户。

validate_cookie()调用另一个函数get_user_data()来执行实际的查询。get_user_data()由几个其他函数和脚本调用,因此它发送的查询非常通用。以下是功能:

代码语言:javascript
复制
function get_user_data($info,$password=Null,$source=Null)
{
  if(!$source)
    {
      $query = "SELECT * FROM `users` WHERE `id` = '".mysql_real_escape_string($info)."' OR `email` = '".mysql_real_escape_string($info)."' OR `cookie`='".mysql_real_escape_string($info)."'"; //Check to see if $info matches any column
    }
  else { $query = "SELECT * FROM `users` WHERE `".mysql_real_escape_string($source)."_token` ='".mysql_real_escape_string($info)."'";} //we got a social token
  $result = mysql_query($query);

  if($result)
    {
      $row = mysql_fetch_array($result);
      if($password)
    {
      if(crypt($password, $row['password']) == $row['password']) //password matching
        {
          return $row;
        } else {return "Password does not match!";}
    }
      else { return $row; }
    } 
  else { return "Could not get result from database!";}
}

本例中的重要查询位于if(!source){}块内。使用validate_cookie()调用get_user_data()的方式,这个查询变成了(我已经测试过它确实变成了这个):

代码语言:javascript
复制
SELECT * FROM `users` WHERE `id` = '8sd8sdvsasdliwerhnbzo823' OR `email`='8sd8sdvsasdliwerhnbzo823' OR `cookie`='8sd8sdvsasdliwerhnbzo823'

因为id是一个int字段,而且email中的所有内容都经过验证,所以从这个查询中选择的唯一行是具有匹配的cookie字段的行。

但是,无论是从PHP脚本调用此查询,还是从PHPMyAdmin手动调用该查询,这都会同时选择目标行和另一行:在其cookie字段中只包含NULL的测试用例。稍微修改散列(这样它就不应该匹配任何东西)仍然选择相同的测试用例。

我的查询是否以我不理解的方式出现错误?是否有一些OR的神秘用途,允许NULL字段进行匹配?任何帮助都将不胜感激。

在我被告知我真的应该使用mysqli之前,是的,我知道。mysql是老板的命令。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-09-05 21:16:19

http://sqlfiddle.com/#!2/0b0832/10/0

它正在将您的散列转换为整数。您的测试ID为3。您的散列以3开头。它使这些值相等。

代码语言:javascript
复制
select cast('3b38f280e0203d7998a0d0898095ed56' as unsigned) as x

产3

就这样把它修好:

代码语言:javascript
复制
SELECT id, email, password, cookie,

case when `email`  = '3b38f280e0203d7998a0d0898095ed56' then 'email'
     when `id`     = '3b38f280e0203d7998a0d0898095ed56' then 'id'
     when `cookie` = '3b38f280e0203d7998a0d0898095ed56' then 'cookie'
     else 'else' end as wtf
FROM `users`
WHERE  
    cast(`id` as char) = '3b38f280e0203d7998a0d0898095ed56' or
    `email`  = '3b38f280e0203d7998a0d0898095ed56' or
    `cookie` = '3b38f280e0203d7998a0d0898095ed56' 

如果传入ID =3,这仍然有效。

票数 2
EN

Stack Overflow用户

发布于 2013-09-05 20:20:52

当且仅当您确信sql语句演变为如下所示:

代码语言:javascript
复制
select a,b,[c ...] from mytable where a='something' or b='something' [or ...]

带着a,b.非空

你只应该得到一行与"a“或"b”,而不是空,并与‘某事’。如果没有,您的数据库/系统/diriver或其他什么都有问题。

有时“其他人都错了”

可以这么说,但这是我做出的一种解释(在我的例子中,php_db2有时只是没有结果)。

特别是

如果(看起来)数据库/驱动程序/安装中存在en错误,您可以尝试使用类似于

代码语言:javascript
复制
select from ... where (a='som' and a is not null) or (b='som' and b is not null...) and so on 

请考虑使用“TODO:等待正确的db安装”这样的标记。

顺便说一下:

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18644262

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档