我尝试使用以下代码在Java 7中使用Java SQL
执行PreparedStatement
查询:
PreparedStatement functionalCRsStatement = con.prepareStatement(
"select * from openquery(SERVER,\n" +
"\t'Select X , Y, Z, A from D r\n" +
"\tINNER JOIN E c\n" +
"\tON r.RNID = c.RNID\n" +
"\twhere c.Y = ?')\n");
functionalCRsStatement.setString(2, x);
我收到以下错误消息:com.microsoft.sqlserver.jdbc.SQLServerException: The index 2 is out of range.
PS:我确定SQL查询的正确性,因为我在没有PreparedStatement
的情况下成功测试了它,我只是用假的(X,Y)替换了查询中列的真实名称,Z)隐藏潜在的机密信息。
编辑:使用setString(1, x)
=>时出现类似错误index 1 is out of range
答案 0 :(得分:2)
正如@JonK评论的那样,你的查询中有撇号,这意味着你的参数实际上在一个字符串中,SQL引擎不会绑定一个值(无论你使用1还是2作为索引):
PreparedStatement functionalCRsStatement = con.prepareStatement(
"select * from openquery(APRPRD,\n" +
"\t'Select X , Y, Z, A from D r\n" +
"\tINNER JOIN E c\n" +
"\tON r.RNID = c.RNID\n" +
"\twhere c.Y = ?')\n");
包含此查询(使用SQL语法高亮显示,显示整个字符串)
select * from openquery(APRPRD,
'Select X , Y, Z, A from D r
INNER JOIN E c
ON r.RNID = c.RNID
where c.Y = ?')
SQL引擎从不检查字符串的内部。如何插入包含问号的字符串?
答案 1 :(得分:1)
您的语句中似乎只有一个?
,因此您无法在functionalCRsStatement.setString(2, x);
中引用第二个索引(2),因为正如它所说的那样,它超出了范围
你应该使用
functionalCRsStatement.setString(1, x);
答案 2 :(得分:1)
您的查询中只有一个绑定变量占位符(?
) - 因此您应该使用1
索引绑定它,而不是2
:
functionalCRsStatement.setString(1, x); // Was 2 in the OP
答案 3 :(得分:0)
您在预准备语句中只能设置一个参数。在预准备语句中设置参数的set方法检查预准备语句中?
的索引,并相应地将值设置为预准备语句。
所以在你的情况下只有1 ?
所以在为预准备语句传递的值数组中是1.并且你试图在索引2处传递值因此它表示
指数2超出范围。
尝试与索引1相同,因为您只需要设置一个参数。
e.g。 functionalCRsStatement.setString(1,x);
记住值x将被存储到预准备语句中第一个索引的?
。
编辑:还要记住要传递的值的类型。如果要将X的值设置为int,则需要调用setInt(1,x)。在这种情况下,它将无法找到第一个索引os String并抛出索引超出范围的错误。
答案 4 :(得分:0)
准备好的语句没有识别任何参数,因为这个查询包含0个参数,因为写错了字符串;试试这个:
PreparedStatement functionalCRsStatement = con.prepareStatement(
"select * from openquery(APRPRD," +
"'Select X , Y, Z, A from D r" +
"INNER JOIN E c" +
"ON r.RNID = c.RNID ')" +
"where c.Y = ?");