简体   繁体   English

如何在Java中的where in子句中的单个变量中执行具有多个值的SQL语句

[英]How to execute a SQL statement in Java with many values in a single variable in where in clause

I have to execute below query through JDBC call 我必须通过JDBC调用执行以下查询

select primaryid from data where name in ("abc", adc", "anx");

Issue is inside in clause I have to pass 11000 strings . 问题在子句中,我必须传递11000个字符串 Can I use prepared statement here? 我可以在这里使用准备好的陈述吗? Or any other solution any one can suggest. 或任何其他可以建议的解决方案。 I dont want to execute the query for each record, as it is consuming time. 我不想为每条记录执行查询,因为这很耗时间。 I need to run this query in very less time. 我需要在非常短的时间内运行此查询。

I am reading the strings from an XML file using DOMParser. 我正在使用DOMParser从XML文件读取字符串。 and I am using sql server db. 并且我正在使用sql server db。

I'm just wondering why you would need to have a manual set of 11,000 items where you need to specify each item. 我只是想知道为什么您需要手动设置11,000个项目,并在其中指定每个项目。 It sounds like you need to bring the data into a staging table (surely it's not been selected from the UI..?), then join to that to get your desired resultset. 听起来您需要将数据带到暂存表中(确保未从UI中选择它。.?),然后将其加入以获得所需的结果集。

Using an IN clause with 11k literal values is a really bad idea - off the top of my head, I know one major RDBMS (Oracle) that doesn't support more than 1k values in the IN list. 使用带有11k文字值的IN子句是一个非常糟糕的主意-浮现在头,我知道一个主要的RDBMS(Oracle)在IN列表中不支持超过1k的值。

What you can do instead: 您可以做什么:

  • create some kind of (temporary) table T_NAMES to hold your names; 创建某种(临时)表T_NAMES来保存您的姓名; if your RDBMS doesn't support "real" (session-specific) temporary tables, you'll have to add some kind of session ID 如果您的RDBMS不支持“真实的”(特定于会话的)临时表,则必须添加某种会话ID
  • fill this table with the names you're looking for 用您要查找的名称填写此表
  • modify your query to use the temporary table instead of the IN list: select primaryid from data where name in (select name from T_NAMES where session_id = ?session_id) or (probably even better) select primaryid from data join t_names on data.name = t_names.name and t_names.session_id = ?session_id (here, ?session_id denotes the bind variable used to pass your session id) 修改您的查询以使用临时表而不是IN列表: select primaryid from data where name in (select name from T_NAMES where session_id = ?session_id)或(可能更好) select primaryid from data join t_names on data.name = t_names.name and t_names.session_id = ?session_id (此处,?session_id表示用于传递会话ID的绑定变量)

A prepared statement will need to know the number of arguments in advance - something along the lines of : 准备好的语句将需要事先知道参数的数量-类似以下内容:

PreparedStatement stmt = conn.prepareStatement(
    "select id, name from users where id in (?, ?, ?)");
stmt.setInt(1);
stmt.setInt(2);
stmt.setInt(3);

11,000 is a large number of parameters. 11,000是大量参数。 It may be easiest to use a 'batch' approach as described here (in summary - looping over your parameters, using a prepared statement each time) 使用此处所述的“批处理”方法可能是最简单的(摘要-遍历您的参数,每次使用准备好的语句循环)

Note - if your 11,000 strings are the result of an earlier database select, then the best approach is to write a stored procedure to do the whole calculation in the database (avoiding passing the 11,000 strings back and forth with your code) 注意-如果您的11,000个字符串是早期数据库选择的结果,那么最好的方法是编写一个存储过程以在数据库中进行整个计算(避免将11,000个字符串与您的代码来回传递)

You can merge all your parameter strings into one bitg string separating by ';' 您可以将所有参数字符串合并为一个bitg字符串,以';'分隔 char 烧焦

bigStrParameter=";abc;adc;anx;" bigStrParameter =“; abc; adc; anx;”

And use LOCATE to find substring. 并使用LOCATE查找子字符串。

select primaryid from data where LOCATE(concat(';',name,';'),?)>=0;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM