2017-05-23 6 views
1

私はこの表から選択しようとしているJDBCで働いている:JDBC MySQLのクエリ構文

CREATE TABLE PERIT (
    COGNOM1 VARCHAR(30) NOT NULL, 
    COGNOM2 VARCHAR(30) NOT NULL, 
    DATANAIX DATE NOT NULL, 
    NOM VARCHAR(30) NOT NULL, 
    NIF VARCHAR(10) NOT NULL, 
    LOGIN VARCHAR(50) NOT NULL, 
    PASSWORDMD5 VARCHAR(50) NOT NULL, 
    NUMERO INT(3) NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (NUMERO) 
); 

私はこのような特定のログインとPASSWORDMD5値を持つ行が存在するかどうかを確認したい:

public int Login(String Login, String pass) { 
    Statement st = null; 
    ResultSet rs = null; 
    int count =0; 
    try { 
     st = con.createStatement(); 
     String consulta = "Select count(*) from Perit p where p.LOGIN ="; 
     consulta += Login; 
     consulta +=" and p.PASSWORDMD5 = MD5("; 
     consulta +=pass; 
     consulta+=")"; 
     rs = st.executeQuery(consulta); 
     while (rs.next()) { 
      count = rs.getInt(1); 
     } 
     st.close(); 
     rs.close(); 
    } catch (SQLException ex) { 
     Logger.getLogger(JDBCMySQL.class.getName()).log(Level.SEVERE, null, ex); 
    } 

    return count; 
} 

しかし、ときに私は、私はこのエラーを取得するLogin("LOGINPERIT1","PASSWORDMDPERIT")を呼び出す:

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:不明で列 'LOGINPERIT1 'WHERE句' sun.reflect.DelegatingConstructorAccessorImpl.newInstanceでsun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)で sun.reflect.NativeConstructorAccessorImpl.newInstance0(ネイティブメソッド) で(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) com.mysql.jdbc.Util.handleNewInstance(Util.java:425) com.mysql.jdbc .Util.getInstance(Util.java:408)at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:943)at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3973)at com .mysql。 jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3909)at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2527) com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2680)at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2497)at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2455)at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:コメント欄で述べたように info.infomila.info.ThreadHandler.run(ThreadHandler.java:56で info.infomila.info.JDBCMySQL.Login(JDBCMySQL.java:139))

+4

PreparedStatementを使用すると、使用するほうがはるかに安全です。あなたのエラーの理由は、 'Strings'はシングルクォートでなければならないということです。それ以外の場合はカラム名として扱います。 –

+1

カラムが存在するかどうかを確認してください" LOGINPERIT1 " –

+0

あなたの文字列、すなわちログインとパスワードは引用されません。それらを引用して確認してください。 –

答えて

1

で1369)あなたが得ている問題は、あなたがあなたのために供給している文字列ログインとパスワードは一重引用符で囲まれていません。

これを回避する簡単な方法は、あなたがコメントで@DevilsHndで述べたように、ログでとパスワードの値で渡さ含めれる前と後に定義されたSQL文字列内の単一引用符を含めることです。

String consulta = "SELECT COUNT(*) FROM Perit WHERE LOGIN = '" + Login + 
"' AND PASSWORDMD5 = MD5('" + pass + "');" 

しかし、これは危険なアプローチです。このアプローチを使用しないと、ログインSQLはSQLインジェクションに耐えることができなくなります。

これを避けるには、PreparedStatementを使用して入力を消毒します。

文の引数を?に置き換え、PreparedStatementクラスのメソッドを使用して設定します。以下は

は、あなたがこれを達成する方法の例です:

String consulta = "SELECT COUNT(*) FROM Perit WHERE LOGIN = ? AND PASSWORDMD5 = MD5(?);" 
try(PreparedStatement pstmt = con.prepareStatement(consulta)) 
{ 
    pstmt.setString(1, login); 
    pstmt.setString(2, pass); 
    try(ResultSet rs = pstmt.executeQuery()) 
    { 
     count = rs.getInt(1); 
    } 
} 
catch (SQLException ex) 
{ 
    Logger.getLogger(JDBCMySQL.class.getName()).log(Level.SEVERE, null, ex); 
} 

あなたの方法では問題の別の領域は、あなたのStatementResultSetはfinallyブロック内で閉じていないことである - これは、内部メモリリークにつながる可能性あなたのコード。

リソースブロックで試してみると、PreparedStatementResultSetがfinallyブロックで閉じられているかのように閉じます。

そして、このxkcdコミックをここに残しておきます!

enter image description here