SQLException:无效的参数索引 1 仅与 PreparedStatement

SQLException: Invalid parameter index 1 only with PreparedStatement

我有一个 webapp(JSP/Servlet) with Tomcat8 + SQL Server2012 JDBC 驱动类型 4: JTDS 旧版本 1.2.5 (http://jtds.sourceforge.net/)

我改变了这种查询,添加了Prepared Statement(服务器分页)

    Sting DDXsql = "SELECT '?' *, ( DDX_RECORD_COUNT / '?' + 1 ) AS DDX_PAGE_COUNT 
FROM 
( SELECT '?' * 
FROM ( SELECT '?' *, 
             (SELECT COUNT(*) " + "FROM " 
          + session.getAttribute("DatabaseName") + ".G1_grid " 
          + sqlFrom 
          + sqlWhere + " "    
            + " )  AS DDX_RECORD_COUNT " 
        + "FROM " + session.getAttribute("DatabaseName") + ".G1_grid " 
        + sqlFrom 
        + sqlWhere + " " 
        +    " ORDER BY '?' '?' , '?' '?' ) AS TMP1 ORDER 
          BY '?' '?', '?' '?') AS r ORDER BY '?' '?', '?'  '?'";

参数:

String top1 = DBManager.getTOP(request, "TOP " + Integer.valueOf((String)ResourceManager.findData("pageSize", request)));
                Integer pagesizeInt = Integer.valueOf((String)ResourceManager.findData("pageSize", request));
                String top2 = DBManager.getTOP(request, "TOP " + Integer.valueOf((String)ResourceManager.findData("ddxrecordcount", request))); 
                String top3= DBManager.getTOP(request, "TOP " + Integer.valueOf((String)ResourceManager.findData("toRange", request)));
                String notSortStr = (String)ResourceManager.findData("notSort", request);
                Object[] values = new Object[] {
                top1,               
                pagesizeInt,
                top2,           
                top3,
                SortKey,
                Sort,
                TotalSortKey,
                Sort,
                SortKey,
                notSortStr,
                TotalSortKey ,          
                notSortStr,     
                SortKey,
                Sort,
                TotalSortKey,
                Sort
                };

之前,我没有使用 PreparedStatement 我有这种查询(将“?”替换为对象数组值,没有 StringEscapeUtils):

    String DDXsql = "SELECT " + 
DBManager.getTOP(request, "TOP " 
+ Integer.valueOf(StringEscapeUtils.escapeSql((String)ResourceManager.findData("pageSize", request)))) + " *, 
( DDX_RECORD_COUNT / " + Integer.valueOf(StringEscapeUtils.escapeSql((String)ResourceManager.findData("pageSize", request))) + " + 1 ) AS DDX_PAGE_COUNT FROM 
( SELECT " 
+ DBManager.getTOP(request, "TOP "
 + Integer.valueOf(StringEscapeUtils.escapeSql((String)ResourceManager.findData("ddxrecordcount", request)))) 
+ " * FROM ( SELECT " + DBManager.getTOP(request, "TOP " + Integer.valueOf(StringEscapeUtils.escapeSql((String)ResourceManager.findData("toRange", request)))) 
+ " *, (SELECT COUNT(*) " 
+ "FROM " + session.getAttribute("DatabaseName") + ".G1_grid " + sqlFrom + sqlWhere + " " + " )  AS DDX_RECORD_COUNT " 
+ "FROM " + session.getAttribute("DatabaseName") 
+ ".G1_grid " + sqlFrom + sqlWhere + " " + " ORDER BY "
 + StringEscapeUtils.escapeSql(SortKey) + " " + StringEscapeUtils.escapeSql(Sort) + ", " 
+ StringEscapeUtils.escapeSql(TotalSortKey) + " " 
+ StringEscapeUtils.escapeSql(Sort) + ") AS TMP1 ORDER BY "
 + StringEscapeUtils.escapeSql(SortKey) + " " 
+ StringEscapeUtils.escapeSql((String)ResourceManager.findData("notSort", request)) 
+ ", " + StringEscapeUtils.escapeSql(TotalSortKey) + " " 
+ StringEscapeUtils.escapeSql((String)ResourceManager.findData("notSort", request)) + " ) AS r ORDER BY " 
+ StringEscapeUtils.escapeSql(SortKey) + " " 
+ StringEscapeUtils.escapeSql(Sort) + ", " 
+ StringEscapeUtils.escapeSql(TotalSortKey) 
+ " " + StringEscapeUtils.escapeSql(Sort) + " ";

上次查询 运行s 没有错误,此查询的 System.out 例如:

SELECT TOP 20 *, ( DDX_RECORD_COUNT / 20 + 1 ) AS DDX_PAGE_COUNT 
FROM 
( SELECT TOP 20 * FROM 
               ( SELECT TOP 20 *, 
                   (SELECT COUNT(*) 
                     FROM SuiteMA_DIP.dbo.G1_grid  
                  WHERE 1 = 1   )  AS DDX_RECORD_COUNT 
                FROM SuiteMA_DIP.dbo.G1_grid  WHERE 1 = 0   ORDER BY DATA_ISCRIZIONE_ORDER DESC, SOGGETTO_RILEVANTE_PAID DESC) AS TMP1 ORDER BY DATA_ISCRIZIONE_ORDER ASC, SOGGETTO_RILEVANTE_PAID ASC ) AS r ORDER BY DATA_ISCRIZIONE_ORDER DESC, SOGGETTO_RILEVANTE_PAID DESC 

但是当我 运行 sql 使用 preparedStatement:

java.sql.SQLException: Invalid parameter index 1.
    at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.getParameter(JtdsPreparedStatement.java:340)
    at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.setParameter(JtdsPreparedStatement.java:409)
    at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.setObjectBase(JtdsPreparedStatement.java:395)
    at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.setObject(JtdsPreparedStatement.java:667)
    at org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement.setObject(DelegatingPreparedStatement.java:188)
    at org.apache.tomcat.dbcp.dbcp2.DelegatingPreparedStatement.setObject(DelegatingPreparedStatement.java:188)
    at it.netbureau.jfx.db.SQLDBManager.execSQL(SQLDBManager.java:57)
    at it.netbureau.jfx.db.SQLDBManager.execSQL(SQLDBManager.java:78)
    at org.apache.jsp.G1.select_jsp._jspService(select_jsp.java:691)

java方法执行查询:

class jfx.db.SQLDBManager.execSQL:

public Object execSQL(PreparedStatement stmt, Object values[], String xmlId)
        throws SQLException
    {
        Object result = null;
        if(stmt == null)
            return null;
        try
        {
            for(int i = 0; i < values.length; i++)
                if(values[i] == null)
                    stmt.setNull(i + 1, 4);
                else
                    stmt.setObject(i + 1, values[i]); <--this give exception!

            if(stmt.execute())                  result = transform(stmt.getResultSet(), xmlId);
        }
        catch(SQLException ex)
        {
            rollback();
            throw ex;
        }
        return result;
    }

怎么了?

非常感谢

罗比

您的查询不包含任何参数,'?'只是一个带有问号的文字字符串,它不是参数。

您也不能参数化对象名称,例如列名称和子句(如 TOP 20),因此即使您将其更改为 - 例如 - order by ?, ... 它也不会工作,因为您将按字符串值排序(所有行都相同,因此实际上您根本不会排序)。

要执行您想执行的操作,您需要将列名(和其他子句)连接到查询字符串中。这也意味着您可能会面临 SQL 注入:请务必仔细检查这些值(例如针对允许值的白名单)。