绑定参数传入多值时SQL IN子句查询无结果问题咨询
问题原因
- 预编译SQL的绑定参数会把传入的所有内容统一识别为单个参数值,不会解析内容中的SQL语法符号(比如逗号、括号)。你传入
(1111111111,2222222222,3333333333)时,数据库实际执行的匹配逻辑等价于phone_number = '(1111111111,2222222222,3333333333)',自然匹配不到存储的单条手机号记录。 - 仅传入单个手机号时,参数值和
phone_number字段的存储值完全一致,所以可以正常返回结果。
解决方法
方案1:动态拼接IN列表
仅适用于传入的手机号完全可控、无外部用户输入的场景,直接把多个手机号拼入SQL语句,不使用单个绑定参数:
select * From table r where account_id = 1111 and phone_number in (1111111111,2222222222,3333333333)
注意:该方案存在SQL注入风险,禁止用于有用户自定义输入的场景。
方案2:拆分传入的字符串参数
利用数据库自带的字符串拆分函数,把逗号分隔的手机号参数拆分为多个独立值后再匹配,不同数据库的语法略有区别:
- MySQL示例:
select * From table r where account_id = 1111 and FIND_IN_SET(phone_number, replace(replace(:phone, '(', ''), ')', '')) > 0
- Oracle示例:
select * From table r where account_id = 1111 and phone_number in ( select regexp_substr(replace(replace(:phone, '(', ''), ')', ''), '[^,]+', 1, level) from dual connect by regexp_substr(replace(replace(:phone, '(', ''), ')', ''), '[^,]+', 1, level) is not null )
- PostgreSQL示例:
select * From table r where account_id = 1111 and phone_number = any(string_to_array(trim('()' from :phone), ',')::bigint[])
方案3:使用数组类型绑定参数
如果你的数据库和驱动支持数组类型参数,直接把手机号列表作为数组传入绑定参数即可,无需处理字符串拆分,同时可以防范SQL注入,以PostgreSQL为例:
select * From table r where account_id = 1111 and phone_number = any(:phone_array)
内容的提问来源于stack exchange,提问作者Manish
相关产品推荐
相关产品推荐

