使用 WHERE IN SQL 子句将字符串值从单个值拆分为多个值以获取数据
Posted
技术标签:
【中文标题】使用 WHERE IN SQL 子句将字符串值从单个值拆分为多个值以获取数据【英文标题】:Split String value from single to multiple values to fetch data using WHERE IN SQL clause 【发布时间】:2021-12-07 21:35:05 【问题描述】:我有一个请求参数,它可以使用@RequestParam
接受单个或逗号分隔的值。
您能帮我分解或拆分逗号分隔值的字符串,以便在 WHERE IN 查询子句中传递这些逗号分隔值时使用它吗?
这是网址的样子:
deviceName
单值参数:getDevices?deviceName=Laptop
deviceName
逗号分隔值的参数:getDevices?deviceName=Laptop,Smartphone,Camera,Television
目前我的代码是这样的:
private List<Devices> processDisplay(List<String> deviceName)
Parameters parameters = new Parameters();
parameters.setDeviceName(!deviceName.isEmpty() ? deviceName : null); \\deviceName is List<String> of type, EDITED: also added null checker
List<Devices> devices = devicesRepository.getDevices(parameters);
;
如何将此逗号分隔值传递给 SQL WHERE IN,以便它接受分解的字符串到 4 条记录中?
这是我的Repository
我的 SQL 所在的位置:
public List<Devices> getDevices (Parameters parameters)
StringBuilder sql = new StringBuilder("SELECT * FROM devices d ");
MapSqlParameterSource parameterSource = new MapSqlParameterSource();
if (!parameters.getDeviceName().isEmpty()))
sql.append(" WHERE d.deviceName IN (:deviceName)");
parameterSource.addValue("deviceName",parameters.getDeviceName().trim())
这样它会产生这样的结果:
SELECT *
FROM devices d
WHERE d.deviceName IN ('Laptop','Smartphone','Camera','Television')
不是这样的:
SELECT *
FROM devices d
WHERE d.deviceName IN ('Laptop, Smartphone,Camera,Television')
非常感谢您的帮助!
【问题讨论】:
【参考方案1】:您可以接受devicesNames
中的List<String>
,将它们传递给您的setDeviceNames()
方法,该方法也将接受List<String>
,您将在此处传递它们:
parameterSource.addValue("deviceName", parameters.getDeviceNames());
【讨论】:
谢谢!但是,当我的devicesName
参数没有传递任何值时,为什么我会得到 null 作为响应?考虑到我创建了一个条件,其中 sql WHERE IN
将仅在 devicesName
具有值时追加,否则将返回所有设备。我是这样做的if (!parameters.getdevicesName().isEmpty()) sql.append(" WHERE d.deviceName IN (:deviceName)"); parameterSource.addValue("deviceName", parameters.getDeviceName());
可能是因为传递了一个空列表,它通过了您的 if 条件检查,您也可以对其进行调试和验证。因此,您也可以在将条件添加到 sql 查询之前添加一个 !list.isEmpty() 检查。
我看到您编辑了您的评论。除了当前的 !isEmpty() 检查之外,您可以添加一个非空检查吗?另外,你能用你最近的代码更新你的帖子吗?
我添加了一个空检查器并用最近的代码更新了我的帖子,但我仍然遇到这个API Error.: null
改变这个:parameters.setDeviceName(!deviceName.isEmpty() ? deviceName : null); to: if (deviceName != null && !deviceName.isEmpty()) set.... 这样你就保证你只为你的对象设置一个非空且有效的值【参考方案2】:
只需替换
sql.append(" WHERE d.deviceName IN (:deviceName)")
与
sql.append(" WHERE d.deviceName = any(string_to_array(:deviceName, ','))")
您的逗号分隔参数将被拆分为一个数组。 IN (<list>)
和 = any(<array>)
在这种情况下是等价的。
结果将是
SELECT *
FROM devices d
WHERE
d.deviceName = any(string_to_array('Laptop,Smartphone,Camera,Television', ','))
使用any
可以释放大量能量。有兴趣的可以看看here。
【讨论】:
以上是关于使用 WHERE IN SQL 子句将字符串值从单个值拆分为多个值以获取数据的主要内容,如果未能解决你的问题,请参考以下文章
我们应该在检索数据时避免 DB2 SQL 中的 IN 子句吗?