如何在类似 PostgreSQL 的查询中正确转义双引号?
Posted
技术标签:
【中文标题】如何在类似 PostgreSQL 的查询中正确转义双引号?【英文标题】:How do I properly escape double quotes in a PostgreSQL like query? 【发布时间】:2021-11-11 18:44:22 【问题描述】:我有一个 PostgreSQL 表,其中 YAML 数据存储在一个文本字段中。
我正在尝试查找密钥已从 false 更改为 true 的所有实例。
audited_changes: "hide_on_map"=>[false, true]
我可以通过对属性 hide_on_map 的类似查询轻松找到此键的所有实例
[3] pry(main)> like_query = ActiveRecord::Base.send(:sanitize_sql_like, 'hide_on_map')
Audited::Audit.where(auditable_type: 'Lot').where('audited_changes like ?', "%#like_query%").count
(245.8ms) SELECT COUNT(*) FROM "audits" WHERE "audits"."auditable_type" = $1 AND (audited_changes like '%hide\_on\_map%') [["auditable_type", "Lot"]]
=> 1710
但是,添加双引号会破坏这一点
[4] pry(main)> like_query = ActiveRecord::Base.send(:sanitize_sql_like, '"hide_on_map"')
Audited::Audit.where(auditable_type: 'Lot').where('audited_changes like ?', "%#like_query%").count
(238.5ms) SELECT COUNT(*) FROM "audits" WHERE "audits"."auditable_type" = $1 AND (audited_changes like '%"hide\_on\_map"%') [["auditable_type", "Lot"]]
=> 0
更不用说完整的查询了
[5] pry(main)> like_query = ActiveRecord::Base.send(:sanitize_sql_like, '"hide_on_map"=>[false, true]')
Audited::Audit.where(auditable_type: 'Lot').where('audited_changes like ?', "%#like_query%").count
(245.0ms) SELECT COUNT(*) FROM "audits" WHERE "audits"."auditable_type" = $1 AND (audited_changes like '%"hide\_on\_map"=>[false, true]%') [["auditable_type", "Lot"]]
=> 0
开始陷入转换为 JSONB 的困境,但这增加了一些我不想解决的额外复杂性。对格式正确的 LIKE 子句的建议?
对于那些询问,此查询的两个示例直接在 SQL 中的 psql 提示符下。
select count(*) from audits where audited_changes like '%"hide\_on\_map"%';
select count(*) from audits where audited_changes like '%\"hide\_on\_map\"%';
两者都产生 0 个结果。
【问题讨论】:
使用准备好的语句而不是 SQL 注入。 您在报价前尝试过使用 \ 吗? @TheImpaler 似乎没有什么不同。 @EmilienBaudet 我有。没有效果。我已经用 psql 直接在 SQL 中试过了,也没有用。 @max 这是我对存储数据的愚蠢误解。请参阅下面的答案和我的评论。 【参考方案1】:问题是在 YAML 中没有一种独特的方式来表达该数据:
hide_on_map:
- no
- yes
"hide_on_map": [false, true]
都是您数据的有效 YAML 表示形式。
我担心您无法避免使用某些本机类型,或者至少是“压缩”JSON 文本(其中包含字面意义上的 '"hide_on_map":[false,true]'
。
【讨论】:
我觉得这里有两个选择;创建一个 JSON/JSONB 列并使用 YAML 解析器转换遗留数据并将其放回数据库中,或者接受数据不可查询的事实。 @rewritten 这是一个正确的答案,但我很愚蠢。在 Rails 控制台中查看数据时,它被转换为后来的表示形式,即我发布的那个,但存储的值处于您提到的状态。我没有正确检查原始审计数据是一个非常愚蠢的错误。感谢您的帮助,很抱歉浪费了您的时间!以上是关于如何在类似 PostgreSQL 的查询中正确转义双引号?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 HTML 作为 PostgreSQL 插入查询中的值处理?
如何使用 Java 在 PostgreSQL 中安全地转义 SQL 的任意字符串
在没有 PreparedStatement 的情况下如何正确转义字符串?