【问题标题】:SQL syntax error when connecting with java and using " ' "与 java 连接并使用“'”时出现 SQL 语法错误
【发布时间】:2014-11-02 16:14:49
【问题描述】:

我已经用 java 小程序连接了一个访问数据库。在其中,我在与学校合作时给出了学生及其学校的价值观,有两所学校(假设):

小花学校
圣若瑟学校

我有一个方法存储和 getchestname(它用于校际比赛。将箱子名称作为唯一 ID)。两个函数运行sql命令如下:

//getchestname :

        ResultSet rs = db.exec("SELECT * FROM Pariticipants WHERE `school` = '"+schools[sc][1]+"' AND event = '"+events[ev][1]+"' AND category = '"+cat[ca][1]+"' AND gender = '"+g2+"'");

//Store:

    rs = db.exec("INSERT INTO Pariticipants ( school , name, event, category , gender ,chestname ) VALUES  ('"+schools[sc][1]+"','"+name+"','"+events[ev][1]+"','"+cat[ca][1]+"','"+g+"','"+cname+"')");

当学校设置为小花学校时,它工作得很好,但是当我使用后者时,它给出了这个错误:

java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver] Syntax error (missing operator) in query expression '`school` = 'St. Joseph\'s school' AND event = '50 m Race' AND category = 'Primary' AND gender = 'Boy''.

我认为这是由于撇号 (')。

编辑: DBConn.java(db connection . early)

import java.sql.*;

/**
 * Write a description of class DBConnector here.
 * 
 * @author Darshan Baid
 * @version (a version number or a date)
 */
public class DBConn
    {
        String accessFileName = "C:\\Users\\Darshan\\Documents\\Database1.accdb";
        Connection con;
        public ResultSet exec(String query)
        {
            try{
                Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);

                stmt.execute(query); // execute query in table student

                ResultSet rs = stmt.getResultSet(); // get any Result that came from our query
                return rs;
            }
            catch(Exception e)
            { 
                e.printStackTrace(); 
                return null;
            }
        }
        public void connect() {

            try {

                Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

                String connURL="jdbc:odbc:DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ="+this.accessFileName+";";

                this.con = DriverManager.getConnection(connURL, "","");

            }
            catch(Exception e)
            { 
                e.printStackTrace(); 
            }
        }
        public boolean close()
        {
            try{
                con.close();
                return true;
            }

            catch(Exception e)
            { 
                e.printStackTrace(); 
                return false;
            }
        }

    }

现在:

import java.sql.*;

public class DBConn
    {
        String accessFileName = "C:\\Users\\Darshan\\Documents\\Database1.accdb";
        Connection con;
        public ResultSet exec(String query)
        {
            try{
                Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);

                stmt.execute(query); // execute query in table student

                ResultSet rs = stmt.getResultSet(); // get any Result that came from our query
                return rs;
            }
            catch(Exception e)
            { 
                e.printStackTrace(); 
                return null;
            }
        }
        public ResultSet exec(String query,String[] ar)
        {
            try{
                PreparedStatement userRecord_stmt = con.prepareStatement(query);

                for(int i = 0; i< ar.length;i++)
                    userRecord_stmt.setString(1,ar[i]);

                    ResultSet userRecord_rs = userRecord_stmt.executeQuery();

                    return userRecord_rs;


            }catch(Exception e)
            {
                e.printStackTrace();
                return null;
            }
        }
        public void connect() {

            try {

                Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

                String connURL="jdbc:odbc:DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ="+this.accessFileName+";";

                this.con = DriverManager.getConnection(connURL, "","");

            }
            catch(Exception e)
            { 
                e.printStackTrace(); 
            }
        }
        public boolean close()
        {
            try{
                con.close();
                return true;
            }

            catch(Exception e)
            { 
                e.printStackTrace(); 
                return false;
            }
        }
    }

并更改为胸名功能。 :

    String ar[] = {schools[sc][1],events[ev][1],cat[ca][1],g2};
    //ResultSet rs = db.exec("SELECT * FROM Pariticipants WHERE `school` = '"+schools[sc][1]+"' AND event = '"+events[ev][1]+"' AND category = '"+cat[ca][1]+"' AND gender = '"+g2+"'");
    ResultSet rs = db.exec("SELECT * FROM Pariticipants WHERE `school` = ? AND `event` = ? AND `category` = ? AND `gender` = ?",ar);

面临的错误:

java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver]COUNT field incorrect

【问题讨论】:

    标签: java sql ms-access jdbc-odbc


    【解决方案1】:

    不要通过连接值来创建SQL 查询。在您的情况下,您正面临 SQL 注入。您的值具有 Access 使用的特殊字符 '。避免这种做法。相反,请使用 PreparedStatement

    Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/demo", "root", "root");
    PreparedStatement userRecord_stmt = con.prepareStatement("SELECT * FROM Pariticipants WHERE `school` = ? AND event = ? AND category = ? AND gender = ?");
    userRecord_stmt.setString(1,schools[sc][1]);
    userRecord_stmt.setString(1,events[ev][1]);
    userRecord_stmt.setString(1,cat[ca][1]);
    userRecord_stmt.setString(1,g2);
    ResultSet userRecord_rs = userRecord_stmt.executeQuery();
    

    我不确定你的表的DataType,所以我在每种情况下都使用setString

    【讨论】:

    • 我是 java 的 sql 新手。我的 db 连接如下:Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); String connURL="jdbc:odbc:DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DBQ="+this.accessFileName+";"; 和 sql 执行 Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); stmt.execute(query); // execute query in table student ResultSet rs = stmt.getResultSet(); 我应该做些什么改变
    • 将 Statement 更改为 PreparedStatement 会有帮助
    • @DarshanJain 是的,PreparedStatement 是最佳实践。并且不要在评论中粘贴您的代码,只需编辑您的问题。
    • 我刚刚将其更改为 PreparedStatement 但现在,当我运行应用程序的 main func 时,它什么也没显示.. 等等,我正在编辑问题
    • 你需要在stmt [PreparedStatement] 中设置值,就像我使用的那样。
    【解决方案2】:

    我可能会因此受到批评,但我使用函数 q() 自动引用字符串。它和参数化所有东西一样安全,而且对于快速和肮脏的东西来说非常干净。

    rs = db.exec("INSERT INTO Pariticipants ( school , name, event, category , gender ,chestname ) 
    VALUES  (" + q(schools[sc][1]) + "," + q(name) + "," + q(events[ev][1]) 
     + ","+ q(cat[ca][1]) + "," + q(g) + "," + q(cname) + ")");
    
    
    Public Function q(i As Variant) As String
        q = QuoteWithEscape(i, "'")
    End Function
    
    Public Function QuoteWithEscape(i As Variant, QuoteChar As String) As String
        If QuoteChar = "" Then
            QuoteWithEscape = CStr(i)
            Exit Function
        End If
    
        If IsNull(i) Then
            QuoteWithEscape = QuoteChar & QuoteChar
        Else
            If InStr(i, QuoteChar) = 0 Then
                QuoteWithEscape = QuoteChar & i & QuoteChar
            Else
                QuoteWithEscape = QuoteChar & Replace(CStr(i), QuoteChar, QuoteChar & QuoteChar, , vbTextCompare) & QuoteChar
            End If
        End If
    End Function
    

    【讨论】:

      猜你喜欢
      • 2020-07-21
      • 2018-12-03
      • 1970-01-01
      • 2020-05-05
      • 1970-01-01
      • 1970-01-01
      • 2019-05-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多