6

我确实从这个 Question PreparedStatement IN 子句替代方案中阅读了解决方案?. 但在我的例子中,我在 In 子句中有大约 5000 个参数,它会导致 java.sql.SQLException: Prepared or callable statement has more than 2000 parameter marker。

我正在使用类似的 SQL

String sql = "select * from project in " + projectIds.toString() 

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

我试着用

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

但它最终会出现不正确的语法错误。

有什么解决办法???

4

3 回答 3

2

Hogan 建议使用桌子代替是一个很好的建议。我唯一要更改的是查询,因为JOIN为 tablelist 中的每个值生成一行。相反(猜测你的列名)

select * from project 
where projectID in (select id from tablelist)

或者

where exists (select 1 from tablelist where id = projectID)
于 2013-03-14T02:57:22.023 回答
1

最好的方法是不使用 in 语句。相反,您应该将要检查的所有值放在一个表中并使用连接。

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

 select *
 from project
 join tablelist on project.project = tablelist.id

这会快得多,因为 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

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

于 2013-03-14T02:46:46.970 回答
1

select * from project in " + projectIds.toString()

语法不正确,应该是这样的

select * from project where id in (" + projectIds + ")";
于 2013-03-14T03:52:25.167 回答