使用 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&lt;String&gt;,将它们传递给您的setDeviceNames() 方法,该方法也将接受List&lt;String&gt;,您将在此处传递它们:

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 (&lt;list&gt;)= any(&lt;array&gt;) 在这种情况下是等价的。 结果将是

SELECT * 
FROM devices d 
WHERE 
  d.deviceName = any(string_to_array('Laptop,Smartphone,Camera,Television', ','))

使用any 可以释放大量能量。有兴趣的可以看看here。

【讨论】:

以上是关于使用 WHERE IN SQL 子句将字符串值从单个值拆分为多个值以获取数据的主要内容,如果未能解决你的问题,请参考以下文章

将数组转换为 WHERE IN mysql 子句的格式

将 IN() 用于数组的 PL/SQL where 子句

我们应该在检索数据时避免 DB2 SQL 中的 IN 子句吗?

SQL 在 WHERE IN 子句中使用 CASE 语句

PL/SQL - 在 Where In 子句中使用“列表”变量

SQL Server:NOT IN in where 子句不能与 NVARCHAR 一起使用