在IN子句中包含数千个参数的PreparedStatement

Wan*_*Wei 6 java sql sql-server sql-server-2005 jdbc

我确实从这个问题PreparedStatement IN子句替代品中读到了解决方案吗?.但就我而言,我在一个In子句中有大约5000个参数,它会导致java.sql.SQLException:Prepared或callable语句有超过2000个参数标记.

我正在使用SQL之类的

String sql = "select * from project in " + projectIds.toString() 
Run Code Online (Sandbox Code Playgroud)

projectIds是一个StringBuilder,就像"(1,2,3,4 ....)"但代码安全报告说它可能会导致sql注入.所以我必须使用?占位符以避免它.

我试着用

String sql = "select * from project where charindex(','+convert(varchar(max),id)+',', ?)>0";
statement.setString(1,projectIds.toString);//projectIds like ",1,2,3,4,"..
Run Code Online (Sandbox Code Playgroud)

但最终会出现错误的语法错误.

有什么办法吗?

Hog*_*gan 1

执行此操作的最佳方法是不使用 in 语句。相反,您应该将要检查的所有值放入表中并使用联接。

例如,如果您有一个包含一列(称为 id)且包含列表的表,那么您的语句将如下所示:

 select *
 from project
 join tablelist on project.project = tablelist.id
Run Code Online (Sandbox Code Playgroud)

这会快得多,因为 SQL 服务器非常擅长快速执行连接。


您也可以使用 CTE 来完成此操作。例如:

WITH tablelist as
(
   SELECT 1 AS id
   UNION ALL
   SELECT 3
   UNION ALL
   SELECT 4
   UNION ALL
   SELECT 5
   UNION ALL
   SELECT 6
   UNION ALL
   SELECT 7
   // More if needed
)
select *
from project
join tablelist on project.project = tablelist.id
Run Code Online (Sandbox Code Playgroud)

这可以作为一个大查询发送并且可以工作。您唯一的限制是查询的最大大小,我不知道是否存在这样的限制。