2013-04-24 59 views
1

大家早上好! 我已經創建了一個有一些單選按鈕的jsp頁面。現在我正在接收servlet中數組中單選按鈕的用戶響應。現在我想將這些數組項目發送到我的oracle數據庫表中。 但我遇到問題。 代碼的JSP頁面:將數組的元素傳遞給使用for循環的Oracle數據庫表

<%@page import="java.util.Calendar"%> 
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" 
pageEncoding="ISO-8859-1"%> 
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 
<title>Insert title here</title> 
</head> 
<body> 
<form action="TestAms" method="post"> 
<% 
Calendar cal = Calendar.getInstance(); 
int md = cal.getActualMaximum(Calendar.DATE); 
    for(int i = 0; i <= md; i++){ 
     %> 
      <input type="radio" name="<%= i%>" value="<%=i %>"> 
     <% 
    } 
%> 
<input type="submit" value="SUBMIT"> 
</form> 
</body> 
</html> 

和servlet的代碼是:

import java.io.IOException; 
import java.io.PrintWriter; 
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.PreparedStatement; 
import java.sql.SQLException; 
import java.sql.Statement; 
import java.util.Calendar; 
import java.util.Enumeration; 
import java.util.Hashtable; 

import javax.servlet.ServletException; 
import javax.servlet.annotation.WebServlet; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

public class TestAms extends HttpServlet { 

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
    PrintWriter out = response.getWriter(); 

    Connection conn = null; 
    PreparedStatement pstmt = null; 

    Calendar cal = Calendar.getInstance(); 
    int md = cal.getActualMaximum(Calendar.DATE); 
    int count =0; 
    String s[] = new String[md+1]; 

    String jan = "JAN"; 
    String query; 

    try { 
     Class.forName("oracle.jdbc.driver.OracleDriver"); 
     conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE","urja","urja"); 

     for (int y=1; y<=md; y++){ 
      s[y] = request.getParameter(Integer.toString(y)); 
      out.println(s[y]); 
      if(y < md){ 
       int z = y+1; 
       out.println("db var : " + z); 
       query = "UPDATE V_TEST SET \"" + z + "\" = ? WHERE V_MONTH = '"+ jan +"'"; 
       pstmt = conn.prepareStatement(query); 
       pstmt.setString(z, s[y]);     //getting error in this line as per the debug report. 
       int i = pstmt.executeUpdate(); 
       out.println("inserted : " + i); 
      } 
     } 

     } catch (ClassNotFoundException e) { 
      e.printStackTrace(); 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     }  
    finally { 
     if (conn != null) { 
      try { 
       conn.close(); 
       pstmt.close(); 
      } 
      catch (SQLException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 
} 

我的表的SQL是:

CREATE TABLE "V_TEST" 
( "V_MONTH" VARCHAR2(4000) NOT NULL ENABLE, 
"1" VARCHAR2(4000), 
"2" VARCHAR2(4000), 
"3" VARCHAR2(4000), 
"4" VARCHAR2(4000), 
"5" VARCHAR2(4000), 
"6" VARCHAR2(4000), 
"7" VARCHAR2(4000), 
"8" VARCHAR2(4000), 
"9" VARCHAR2(4000), 
"10" VARCHAR2(4000), 
"11" VARCHAR2(4000), 
"12" VARCHAR2(4000), 
"13" VARCHAR2(4000), 
"14" VARCHAR2(4000), 
"15" VARCHAR2(4000), 
"16" VARCHAR2(4000), 
"17" VARCHAR2(4000), 
"18" VARCHAR2(4000), 
"19" VARCHAR2(4000), 
"20" VARCHAR2(4000), 
"21" VARCHAR2(4000), 
"22" VARCHAR2(4000), 
"23" VARCHAR2(4000), 
"24" VARCHAR2(4000), 
"25" VARCHAR2(4000), 
"26" VARCHAR2(4000), 
"27" VARCHAR2(4000), 
"28" VARCHAR2(4000), 
"29" VARCHAR2(4000), 
"30" VARCHAR2(4000), 
"31" VARCHAR2(4000) 
); 

,我收到完整的錯誤:

java.sql.SQLException: Missing IN or OUT parameter at index:: 1 
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134) 
at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:179) 
at oracle.jdbc.driver.OracleStatement.checkBindsInAndOut(OracleStatement.java:1876) 
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2638) 
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:589) 
at TestAms.doPost(TestAms.java:47) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) 
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) 
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:931) 
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) 
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004) 
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589) 
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
at java.lang.Thread.run(Unknown Source) 

My Database looks like this

我想在每列中存儲日期(jsp頁面中單選按鈕的日期已被檢查)。

這是我的jsp頁面。 jsp page

在此先感謝。

+0

有什麼問題? – Zyerah 2013-04-24 03:22:09

回答

1

說實話,這裏有很多你做錯了。

首先,使用參數化的SQL。使用PreparedStatements。 請不要使用串聯來建立您的SQL字符串,除非您絕對必須,否則您會發現自己是SQL注入攻擊的受害者。現在討論SQL注入是強制性的,下面是關於SQL注入的xkcd漫畫的鏈接:http://www.xkcd.com/327

其次,您正在收到ORA-00927錯誤,因爲您發送到數據庫的SQL語句無效。我不知道方括號在Oracle SQL中的任何地方都是有效的(字符串和雙引號標識符之外)。 s[md]可能具有作爲Java表達式的值,但是在字符串內部它不會被評估,因此數據庫被要求執行查詢UPDATE V_TEST SET s[md]= ...,它不理解。

甲骨文知道,SQL語句的形式應該

UPDATE table SET column = value .... 

有了您的查詢它獲得儘可能UPDATE V_TEST SET s,想到s是列的名稱,然後它得到了驚訝,因爲它找到了一個[當它想要一個=

此外,您的列名稱是數字,因此它們需要用雙引號包圍,否則Oracle會認爲您正在嘗試爲數字指定值。 UPDATE V_TEST SET 1 = 'xyz'是無效的SQL,UPDATE V_TEST SET "1" = 'xyz'是。

代替寫信

stmt = conn.createStatement(); 
    //Query is not right 
    int i = stmt.executeUpdate("UPDATE V_TEST SET s[md] = '"+s[md]+"' WHERE V_MONTH = '"+jan+"'"); 

// Use \" to escape the double-quotes, so that the query ends up like 
    // UPDATE V_TEST SET "30" = ? WHERE V_MONTH = ? 
    // In this case we have to use string concatenation to build up the query, 
    // but we're only inserting an integer so this won't be a problem. 
    String sql = "UPDATE V_TEST SET \"" + md + "\" = ? WHERE V_MONTH = ?"; 

    // stmt will need to be declared as a PreparedStatement, not a Statement. 
    stmt = conn.prepareStatement(sql); 

    // Set the values for the two '?' placeholders. 
    stmt.setString(1, s[md]); 
    stmt.setString(2, jan); 

    int i = stmt.executeUpdate(); 

這應該可以解決前兩個你的問題。

第三,似乎你沒有連接,因爲你沒有關閉你的連接(除非你的查詢成功了,他們目前沒有這樣做)。您應該在finally區塊中關閉它們,因爲這可確保即使在引發異常時它們也會關閉。

你應該做類似如下(這是一個草圖):

Connection conn = null; 
    try { 
     // get database connection ... 

     // do stuff with connection ... 
    } 
    catch (SQLException e) { 
     // handle error connecting to the database or using it 
    } 
    finally { 
     if (conn != null) { 
      try { 
       conn.close(); 
      } 
      catch (SQLException e) { 
       // handle error disconnecting from the database. 
      } 
     } 
    } 

除了關閉連接,這也是很好的做法,關閉Statement S和PreparedStatement一度您與他們完成。

第四,每次通過循環時,都會創建一個新的數據庫連接(這將在服務器上創建一個新進程)。這完全沒有必要。您應該在循環之前創建一次數據庫連接,在整個循環中使用相同的連接,並且只在循環結束時關閉連接。因爲你在一個循環中創建了這麼多的連接,而不是關閉它們中的任何一個,所以你最終會很快達到數據庫進程的極限。

第五,我強烈建議使用Oracle JDBC驅動程序(類名oracle.jdbc.OracleDriver,在一個名爲ojdbc6.jar或類似JAR),而不是「老」 JDBC-ODBC橋驅動程序,這will be removed from Java in Java 8

第六,即使您的SQL按我的建議修復,也不太可能做到您想要的。目前它只會爲當前月份的最後一天對應的列設置一個值。您是否有意更新名稱爲y的專欄?

編輯響應您編輯的問題:問題是這條線:

  pstmt.setString(z, s[y]);     //getting error in this line as per the debug report. 

這應該是

  pstmt.setString(1, s[y]); 

人數1是佔位?在索引查詢。這些索引從1開始。在查詢中只有一個佔位符,因此索引爲1.

+0

!請看看編輯後的代碼。 – Mavrick 2013-04-27 08:52:44

+0

@Walid請解決這個問題。 – Mavrick 2013-04-27 09:00:45

+0

@Mavrick:看到我編輯的答案。 – 2013-04-27 11:13:45

相關問題