【发布时间】: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 这是我对存储数据的愚蠢误解。请参阅下面的答案和我的评论。
标签: sql ruby-on-rails postgresql ruby-on-rails-5