这个SQL语法有什么问题?

问题描述:

我想用java servlet构建注册系统。并将数据插入到mySQL数据库中。但是我得到一个语法错误。我刚刚读完Wiley mySQL和Java开发人员指导书。这个SQL语法有什么问题?

我对servlet编程还不太熟悉,所以如果有简单的方法可以做,请告诉我。

package com.app.base; 

import java.io.IOException; 
import java.io.PrintWriter; 
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.ResultSet; 
import java.sql.Statement; 

import javax.servlet.RequestDispatcher; 
import javax.servlet.ServletException; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

import com.app.pojo.*; 

public class RegisterServlet extends HttpServlet{ 

MySqlDB mysql; 

@Override 
public void init() throws ServletException { 
    // TODO Auto-generated method stub 
    mysql = new MySqlDB(); 

} 

@Override 
protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
     throws ServletException, IOException { 

    PrintWriter out = null; 
    //Connection connection = null; 
    //Statement statement; 
    //ResultSet rs; 

    resp.setContentType("text/html"); 
    out = resp.getWriter(); 


    try{ 
     mysql.createConnection(); 
    }catch(Error e){ 
     out.write("Couldn't connect to mysql"); 
    } 
    String fname = req.getParameter("fname"); 
    String lname = req.getParameter("lname"); 
    String email = req.getParameter("email"); 
    String password = req.getParameter("password"); 
    String city = req.getParameter("city"); 
    String country = req.getParameter("country"); 

    if(fname == null){ 
     String destination = "signup.jsp?error=Complete All Fields"; 
     RequestDispatcher rd = getServletContext().getRequestDispatcher(destination); 
     rd.forward(req, resp); 
    }else if(lname == null){ 
     String destination = "signup.jsp?error=Complete All Fields"; 
     RequestDispatcher rd = getServletContext().getRequestDispatcher(destination); 
     rd.forward(req, resp); 
    }else if(email == null){ 
     String destination = "signup.jsp?error=Complete All Fields"; 
     RequestDispatcher rd = getServletContext().getRequestDispatcher(destination); 
     rd.forward(req, resp); 
    }else if(password == null){ 
     String destination = "signup.jsp?error=Complete All Fields"; 
     RequestDispatcher rd = getServletContext().getRequestDispatcher(destination); 
     rd.forward(req, resp); 
    }else if(city == null){ 
     String destination = "signup.jsp?error=Complete All Fields"; 
     RequestDispatcher rd = getServletContext().getRequestDispatcher(destination); 
     rd.forward(req, resp); 
    }else if(country == null){ 
     String destination = "signup.jsp?error=Complete All Fields"; 
     RequestDispatcher rd = getServletContext().getRequestDispatcher(destination); 
     rd.forward(req, resp); 
    }else{ 

     String sql = "INSERT INTO main.users(first_name, last_name, email, password, city, country, registered_time) VALUES(" 
       + fname +", "+ lname + ", "+ email +", " + password +", " + city +"," + country + ",Now());"; 
     int answer = mysql.insertSQL(sql); 
     if(answer == 1){ 
      resp.sendRedirect("index.jsp?registered=true"); 
      //String destination = "index.jsp?registered=true"; 
      //RequestDispatcher rd = getServletContext().getRequestDispatcher(destination); 
      //rd.forward(req, resp); 
     } 
    } 


} 

} 

这是MySql类来连接。

package com.app.pojo; 

import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.ResultSet; 
import java.sql.SQLException; 
import java.sql.Statement; 

public class MySqlDB{ 

private static String username = "root", password = "root"; 

public Connection createConnection(){ 
    Connection connection = null; 
    try{ 
     //Load the JDBC driver 
     Class.forName("com.mysql.jdbc.Driver"); 

     connection = DriverManager.getConnection("jdbc:mysql://localhost:3306,/main", username, password); 
     //Create a connection to the database 


    }catch(SQLException ex){ 
     System.out.println(ex); 
    }catch(ClassNotFoundException e){ 
     System.out.println(e); 
    } 

    return connection; 
} 

public void runSqlStatement(String sql){ 
    try{ 
     Statement statement = createConnection().createStatement(); 
     //statement executeQuery(Query) 
     boolean rs = statement.execute(sql); 
    }catch(SQLException ex){ 
     System.out.println(ex); 
    } 
} 

public ResultSet executeSQL(String sql){ 

    Statement statement = null; 
    ResultSet rs = null; 

    try{ 
     statement = createConnection().createStatement(); 
     rs = statement.executeQuery(sql); 

     /*while(rs.next()){ 
      System.out.println(rs.getString(1)); 
     }*/ 


    //   rs.close(); 
    //   statement.close(); 
    }catch (SQLException e) { 
     System.out.println(e); 
    } 

    return rs; 
} 

public int insertSQL(String sql){ 

    int rs; 

    try{ 
     Statement statement = createConnection().createStatement(); 
     rs = statement.executeUpdate(sql); 
     return rs; 

    }catch(SQLException ex){ 
     System.out.println(ex); 
     return 0; 
    } 


} 
} 

这是tomcat的控制台

INFO: Reloading Context with name [/Map] has started 
Apr 21, 2012 12:59:14 AM org.apache.catalina.loader.WebappClassLoader clearReferencesJdbc 
SEVERE: The web application [/Map] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered. 
Apr 21, 2012 12:59:17 AM org.apache.catalina.core.StandardContext reload 
INFO: Reloading Context with name [/Map] is completed 

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '********,Colombo,Sri Lanka,Now())' at line 1 
+5

我不是一个java家伙,但是这看起来很容易被注入。 – 2012-04-20 19:53:02

+0

@JeremyHolovacs是对的。你应该使用'PreparedStatement'来代替。 – Ozzy 2012-04-20 19:54:00

尝试......

Connection con = mysql.createConnection(); 
String sql = "INSERT INTO main.users(first_name, last_name, email, password, city, 
country, registered_time) VALUES(?, ?, ?, ?, ?, ?, ?);"; 
PreparedStatement insertStatement = con.prepareStatement(sql); 
insertStatement.setString(1, first_name); 
insertStatement.setString(2, last_name); 
insertStatement.setString(3, email); 
insertStatement.setString(4, password); 
insertStatement.setString(5, city); 
insertStatement.setString(6, country); 
insertStatement.setString(7, new Date()); 
insertStatement.execute(); 

问候。

你需要逃出/报价,您有串在你VALUES部分。您的JDBC驱动程序将为您执行此操作,例如using a PreparedStatement

请注意,如果您保留现有代码或只是添加周围的引号,则您确实存在SQL injection attack的危险。

试着把单引号放在你的变量中。

例:

VALUES('" + myString + "', '" + myOtherString + "')

Colombo,Sri Lanka,Now())' at line 1 

看起来像你缺少你周围的字符串单引号。

String sql = "INSERT INTO main.users(first_name, last_name, email, password, city, country, registered_time) VALUES('" 
       + fname +"', '"+ lname + "', '"+ email +"', '" + password +"',' " + city +"','" + country + "',Now())"; 
+0

-1:仍然容易受到SQL注入的影响。不要这样做 – 2012-04-20 21:19:10

+0

@MarkRotteveel虽然这是真的,但这个问题并没有与SQL注入有任何关系。这确实回答了他为什么会得到例外的问题。 – 2012-04-20 21:22:29

+1

@JamesMontagne我认为,在利用SQL注入之前教育人们比通过给出一个坏的和危险的答案来回答问题更重要。 – 2012-04-20 21:26:07