【问题标题】:SQL get row by int | stringSQL 通过 int | 获取行细绳
【发布时间】:2021-06-25 16:07:15
【问题描述】:

我的 SQL 查询有点卡住了。

我有一个表,其中的行可以通过 id 或哈希字符串来识别...

id short title
1 asdadasdsd foo
2 1qweqweqwe bar
3 yxcyxcyxcy baz

所以 SQL 很简单...

SELECT * FROM table WHERE id=<identifier> OR hash=<identifier>

我发现当我的标识符是散列并且以可以在 id 列中找到的数字开头时,MYSQL 会返回“错误”行。 例如,当我的标识符是“1qweqweqwe”时,结果是第 1 行。 我认为原因是它可能将我的哈希字符串转换为整数?有没有办法禁用这种行为? 或者唯一的方法是将所有哈希重新生成为没有数字的新格式?

感谢您的澄清:)

彼得

【问题讨论】:

  • 这是一个关于 MySql 如何违反 ansi 标准的 ooooold 问题。任何其他数据库,由于字符串和 varchar 之间的转换问题,此查询甚至无法运行。并不是1qweqweqwe 不再匹配 id 1。要完全符合 ansi 标准,您也不会看到 id 2,因为查询只会失败。您需要类似 Sql Server 的 Try_Convert() 来获得更正确的处理。这也是对标准的扩展,但它更符合几乎所有其他数据库的做法。
  • 谢谢乔尔 :)

标签: mysql sql hash


【解决方案1】:

不,您不必重新生成哈希值。如果 id 和 hash 都匹配并且您更喜欢 要基于哈希提取行,那么您可以将哈希作为第一个匹配列条件。基本上它与第一个匹配条件相符。

另外,我想您已经在查询中的哈希字符串中添加了引号。如果不是,请这样做,因为它将验证为字符串。

SELECT * FROM table WHERE hash='<identifier>' OR id=<identifier> 

【讨论】:

  • 实际上我使用框架来构建查询并将所有值作为字符串传递。我将不得不做一些前置逻辑。谢谢你:)
  • @PetrLukáš 这样做的框架往往也会错误地处理 sql 注入。这可能非常危险。这是让您的数据库被黑的一种非常快速的方法。
  • 别担心,框架本身内置了非常好的 SQL 注入保护;)
【解决方案2】:

您似乎将标识符作为字符串传递——因为它是。但随后您正在与一个数字(id)进行比较,并且字符串参数被转换为一个数字。 MySQL 通过转换前导数字(如果有)来做到这一点。

我不喜欢为标识符传递字符串的逻辑,所以我真的建议你修复调用逻辑并调用 either

WHERE id = <int identifier> 

或:

WHERE hash = <string identifier>

但是如果你想保留你当前的版本,你可以转换成一个字符串:

WHERE CAST(id AS CHAR) = <identifier> OR hash = <identifier>

【讨论】:

  • 请注意,转换 id 将阻止 id 列使用任何索引。它正在强制进行表扫描。
  • @JoelCoehoorn 。 . .我认为OR 已经这样做了。
  • 可能。我对 MySql 不太了解,但应该可以进行两次索引搜索而不是表扫描。
  • @JoelCoehoorn:是的,MySQL 将使用这两个不同的索引,并对这两个索引的结果进行合并。
  • 我觉得我的逻辑没问题。 Iam 调用具有 id 数组的方法,这些 id 使用库进行构建查询。我有类似 $selection->whereOr( [ short" => $ids, "id" => $ids ] ); 和构建的查询是: "SELECT * FROM table WHERE ( ( id IN ('94-qweqwe ')) 或 (short IN ('94-qweqwe') ) )
猜你喜欢
  • 2021-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-25
  • 2023-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多