【问题标题】:Using "like" operator in MySQL query including a ColdFusion variable在 MySQL 查询中使用“like”运算符,包括 ColdFusion 变量
【发布时间】:2016-02-24 04:11:56
【问题描述】:

我正在构建一个“相关资源”页面,该页面在我们的图书馆中搜索与特定飞机有关的论文。如果访问者正在研究 XV-1,我想查找标题中包含名称“XV-1”的所有论文。但我不想在 XV-15 上找到任何文件。飞机名称是一个 ColdFusion 变量,我们使用的是 MySQL。

我现在使用的是什么:

WHERE title LIKE <cfqueryparam cfsqltype="cf_sql_varchar" value="%#trim(aircraftDesignation)#%" />

这会按预期返回“XV-1 的转子系统”,但也会返回我们不想要的“使用 RotCFD 预测孤立的 XV-15 转子性能”。

我认为,如果我可以查询飞机名称,而不是立即允许任何数字字符,但允许其他字符,例如撇号或逗号,那可能会起作用。不过,我试过了

'%#trim(aircraftDesignation)#[^0-9]%'

'%#trim(aircraftDesignation)#[!0-9]%'

它们都不返回任何东西。如果可能的话,我将不胜感激在正确方向上的任何帮助或推动!非常感谢您的建议。

更新:我解释得不好。我很抱歉!我们确实有一个飞机名称字段。相关资源查询仅在访问者登陆特定页面时运行。例如,如果他或她登陆 XV-1 页面,则飞机名称将被分配一个值“XV-1”。相关资源的查询会根据分配的飞机名称自动进行(每页不同)。不接受用户输入。

我试图在“XV-1”之后不包含数字是为了防止 XV-15 上的论文出现在 XV-1 页面上。 XV-15 上的论文将显示在 XV-15 页面上,因为“XV-15”是飞机名称。但是关于 XV-167 的论文(如果有的话)不会显示在 XV-15 页面上。

我将其标记为 ColdFusion,因为 Aircraft Designation 是查询中使用的 CF 变量。我使用 SQL 的尝试(以及我对使用 REGEXP 的研究要么失败,因为我似乎没有正确使用该变量。或者在 REGEXP 的情况下,无法将变量与正则表达式结合使用。

我希望这有助于澄清!非常感谢大家的帮助。

另一个更新:像这样使用 REGEXP:

WHERE title REGEXP '#trim(aircraftDesignation)#[^0-9]'

到目前为止工作正常!标题中带有“XV-1”的论文以及“XV-1's”的论文都在展示。但 XV-15 论文不是。我抽查的所有其他搜索似乎都按预期工作。

全文搜索是一个不错的选择,我一定会进一步研究它。感谢大家的帮助和建议!我真的很感激。

【问题讨论】:

  • 您可能想尝试使用 MySql 的 REGEX 运算符而不是 LIKEdev.mysql.com/doc/refman/5.7/en/regexp.html
  • 您如何区分 XV-1 和 XV-15?后者在前者之后有一个数字字符,因此在查询条件之后不允许数字字符在这里没有任何区别。我认为您需要为您的飞机名称指定一个列并对此进行查询。这不是一个真正的 ColdFusion 问题。
  • 您的编程工作最好花在搜索页面上。也许相关的选择会比文本框更好。
  • 谢谢大家。我正在研究 REGEXP 但它似乎是单独使用的,而不是与变量一起使用。不过,我需要阅读更多关于它的内容,所以感谢您的提示!加里和丹,我添加了一个解释,可能会使事情更清楚一点。感谢您的帮助!
  • 不是不能将变量与正则表达式结合使用,而是必须能够将变量内容转化为有效的正则表达式。例如,您可以使用REGEXP with optional word boundaries。当然,从技术上讲,您可以通过 LIKE 匹配获得相同的结果,但是.... sql 几乎肯定会更加复杂,性能可能更低。根据您的需要,另一种选择是full text searching

标签: mysql coldfusion


【解决方案1】:

我要感谢 beloitdavisja 在上面的评论中为我指明了正确的方向:

“您可能想尝试使用 MySql 的 REGEX 运算符而不是 LIKE。dev.mysql.com/doc/refman/5.7/en/regexp.html – beloitdavisja”

这为我提供了我正在寻找的结果,以及许多其他有用的信息。谢谢!根据 Leigh 的观点,这是我最终使用的查询(为简洁起见,省略了 cfqueryparam):

SELECT sku, title, content, fileName
FROM sd_productsearch
WHERE title REGEXP '#trim(aircraftDesignation)#[^0-9]' AND sku NOT LIKE 'v_%' AND status = '1'
ORDER BY title

稍微解释一下:这个查询只提取我们的技术论文,而不是我们一般感兴趣的杂志文章(SKU 编号以“v_”开头)。它也只显示我们图书馆中的活跃论文(状态为 1)。我使用的 REGEXP 允许搜索该飞机页面的特定飞机名称,但之后会过滤掉任何数字。这与我最初尝试做的类似,但我不知道 REGEXP 运算符。所以再次感谢 beloitdavisja!

更新:感谢 Leigh 对范围变量和(尤其是)cfqueryparam 的提醒。如果有人想知道如何将它与 REGEXP 一起使用,这对我有用:

WHERE title REGEXP <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(aircraftDesignation)#[^0-9]">

【讨论】:

  • 那么您最终使用的是什么 SQL?更新您的答案以包含实际 SQL 的 sn-p 将有助于下一个遇到此问题的人。
  • 利好点!我已经编辑了我原来的问题,但你是对的,我得到的答案属于答案! :-) 此外,所指的 sd_productsearch 表是我们完整产品表的新版本,设置为使用全文搜索。感谢您的建议——我也不熟悉全文搜索和单词边界,我们将在其他应用程序中真正使用它们。非常感谢!
  • 很好的后续行动。请记住,REGEXP 具有保留字符,就像任何语言一样。如果#aircraftDesignation# 包含任何这些字符,则可能会破坏 SQL 或产生意外结果。因此,您可能需要添加一些验证。另外,不要忘记限定变量的范围并使用 cfqueryparam(否则查询很容易受到 sql 注入的攻击!)。
  • 没关系...我看到你正在使用 cfqueryparam 可能只是为了简洁而省略了它:)(更新答案以注意)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多