【问题标题】:Strict matching of strings and integers字符串和整数的严格匹配
【发布时间】:2013-05-20 16:38:14
【问题描述】:

我正在为客户的网站编写一个灵活的搜索机制。我正在利用联合子句查询数据库中的许多不同字段,以搜索用户输入的字符串值。除了一个问题之外,这工作正常。

将文本字符串与当前设置为零的整数进行比较时,匹配始终返回 true。换句话说,根据 MySQL,“email@example.com”等于 0。

我尝试使用 CAST 和 CONVERT 函数将其转换为标准字符串到字符串比较,但我似乎无法正确使用语法。我的尝试要么重复上述问题,要么在某些应该匹配时根本不返回任何行。我还担心这样做会对性能产生影响,因为我正在合并许多工会。

我真正需要的是在输入的字符串和数据库中的值之间进行严格的比较,无论是整数还是字符串。

编辑: 这是一个例子。

CREATE  TABLE `test_table` (
`id` INT NOT NULL AUTO_INCREMENT ,
`email` VARCHAR(255) NOT NULL ,
`phone` BIGINT(19) NOT NULL DEFAULT '0' ,
PRIMARY KEY (`id`) )
ENGINE = MyISAM;

INSERT INTO `test_table` (`id`, `email`, `phone`) VALUES (1, 'email@example.com', 0);

SELECT * FROM test_table WHERE phone = 'email@example.com';

执行此操作,将返回已插入的一行。我的问题是它不应该!

【问题讨论】:

  • 如果您不显示代码,我们无法告诉您您做错了什么。通常您在调用prepare() 时指定要使用的数据类型(假设您使用的是准备好的语句,因为您应该避免 SQL 注入)。
  • 我已经编辑了帖子以提供示例。在字符串到达​​查询之前,我正在处理 SQL 注入和其他安全措施。
  • 在您的示例中,您将字符串与整数进行比较?
  • WHERE phone = 'email@example.com';电话字段是一个整数。它正在与一个字符串进行比较。

标签: mysql


【解决方案1】:

这个查询应该失败:

SELECT * FROM test_table WHERE cast(phone as char) = 'email@example.com';

原来问题的原因是在比较字符串和数字的时候,把字符串转换成数字(所以可以写where phone = '123')。您需要使用字段的显式转换来使其成为字符串到字符串的比较,以防止这种默认转换。

不幸的是,这样的强制转换可能会阻止它使用索引。即使该字段已经是char,演员表显然会阻止它被索引。

您也可以在输入验证期间解决它:如果phone 是整数,则不允许用户在搜索字段中提供非整数值。

【讨论】:

  • 您重复了我在上面的原始帖子中表达的关于性能的一些担忧。索引的使用正是我所暗示的。我很高兴您提出了与我尝试使用的解决方案完全相同的解决方案——CAST 函数。无论哪种情况,您都给了我一个有效的语法示例,这似乎对我有用。我的初始测试没有显示我正在使用的记录数量有任何直接的性能问题,所以我现在可能还好。谢谢。
  • 我在一个有 250 万行的表上试了一下,查询耗时 7 秒。
【解决方案2】:

更换怎么样:

SELECT * FROM test_table WHERE phone = 'email@example.com'

与:

SELECT * FROM test_table WHERE phone = 'email@example.com' and phone <> 0

表示不同。

这对您有用,因为您在电话列中使用 0 表示没有电话号码(尽管使用 NULL 表示没有电话号码会更好)。

【讨论】:

  • 那不一定行得通。如果phone 为1,则WHERE phone = '1email@example.com 为真。
猜你喜欢
  • 2017-05-09
  • 1970-01-01
  • 2014-04-14
  • 2012-07-04
  • 2014-09-18
  • 2018-10-06
  • 2011-06-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多