2016-10-28 48 views
3

我有一個Web應用程序(JSP/Servlet的)與Tomcat8 + SQL Server2012 JDBC驅動程序類型4:JTDS舊版本1.2.5(http://jtds.sourceforge.net/的SQLException:無效的參數指標1只的PreparedStatement

我改變這種查詢,加入準備語句(服務器pagining)

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 
       }; 

之前,我didint使用PreparedStatemen T I有這種查詢(替換對象數組值,而不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) + " "; 

最後查詢沒有錯誤運行,這個查詢的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 

但是當我preparedStatement時運行SQL:

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; 
    } 

怎麼了?

非常感謝您

羅比

回答

3

您的查詢不包含任何參數,一個'?'只是一個字符串與它一個問號,它不是一個參數。

您也無法參數化對象名稱,如列名稱和子句(如TOP 20),所以即使您將其更改爲 - 例如 - order by ?, ...也不行,因爲您將按字符串的值(這對所有行都是一樣的,所以有效的你根本不會被排序)。

要做你想做的事你需要將列名(和其他子句)連接到查詢字符串中。這也意味着你可以打開自己的SQL注入:一定要仔細檢查值(例如,對白名單的允許值)。

+0

您是否知道用於在字符串中跳過/刪除未知SQL的LIB? – robyp7

+2

@ robyp7請注意,所有上限通常被解釋爲喊叫,不要這樣做;但不,我不知道這樣的圖書館。 –

+0

對不起,但我沒有故意......我很害怕..我爲此道歉。 – robyp7

相關問題