Java PreparedStatement:com.microsoft.sqlserver.jdbc.SQLServerException,索引超出范围

时间:2016-07-29 09:26:53

标签: java sql sql-server jdbc

我尝试使用以下代码在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

5 个答案:

答案 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 = ?");