2011-08-05 1 views
3

私はテーブルVIDEO (VideoID int Primary Key, Address Varchar(100))を持っており、与えられたアドレスのビデオがあるかどうかを調べるためにテーブルを検索したいと思います。しかし、このコードがうまくいくかどうか、そしてこれがうまくいくかどうかはわかりません。指定された基準でjavaが存在する場合、データベースをチェックする方法は?

public boolean checkIfVideoExist(String address) throws SQLException { 
    int count = 0; 
    Statement stmt = connection.createStatement(); 
    ResultSet rset = stmt 
      .executeQuery("SELECT Count(VideoID) from VIDEO WHERE Address='" 
        + address + "'"); 
    if (rset.next()) 
     count = rset.getInt(1); 
    if (count == 0) 
     return false; 
    else 
     return true; 
} 
+1

あなたのコードをフォーマットするためのコードの書式設定]ボタンを使用してください: '{}' – Kiril

+2

あなたはSQLインジェクションに広いオープンだが、そうでない場合は非常にあなたがさらに物事を最適化するために行うことができますがありません。 –

+0

@Lirik 4つのスペース文字を挿入するフォーマットを試みましたが、これは何も変更されませんでした –

答えて

3

インデックスが必ずADDRESSに設定されていることを確認してください。次に、クエリが高速に実行されます。

アドレス値をクエリに渡すには、準備されたステートメントを使用することをお勧めします。結果セットとステートメントを閉じる必要があります。

そして

if (count == 0) 
    return false; 
else 
    return true; 

少し奇妙に見えます。

public boolean checkIfVideoExist(String address) throws SQLException { 
    int count = 0; 
    PreparedStatement stmt = null; 
    ResultSet rset = null; 
    try { 
    stmt = connection.prepareStatement(
     "SELECT Count(VideoID) from VIDEO WHERE Address=?"); 
    stmt.setString(1, address); 
    rset = stmt.executeQuery(); 
    if (rset.next()) 
     count = rset.getInt(1); 
    return count > 0; 
    } finally { 
    if(rset != null) { 
     try { 
     rset.close(); 
     } catch(SQLException e) { 
     e.printStackTrace(); 
     } 
    }   
    if(stmt != null) { 
     try { 
     stmt.close(); 
     } catch(SQLException e) { 
     e.printStackTrace(); 
     } 
    }   
    }  
} 
+0

コードに構文エラーがあります。それはpreparedStatementではなくprepareStatementである必要があります。 2番目の問題は次のとおりです。rset = stmt.execute(); rset = stmt.executeQuery(); –

+0

申し訳ありませんが、あなたは正しいです。私はコードを更新しました。 'stmt.execute()'はINSERT文で使うことができますが、SELECTクエリでは 'stmt.executeQuery()'を使うべきです。 – vanje

0
ResultSet rset = stmt.executeQuery("SELECT * from VIDEO WHERE Address='" + address + "'"); 
return rset.next(); 

はその後、少なくとも一つの一致するレコードがあり、あなたが行われています。 はここに私のコードです。 ....

+0

私はこれが真実だとは思わないが、彼はCOUNT()を行っている –

+0

番号を選択カウントは0を返します。真とブール値を比較することは悪い習慣です。単にOPのようなif(rset.next())を使っても問題ありません。 –

+1

後継者にとって:これは本当に最悪の方法です。ブール値を初期化するためにデータを一括してロードします。また、SQLインジェクション攻撃にも対応しています。 –

2

コードにはSQL Injectionの脆弱性があります。文字列連結を使用してSQLクエリを構築する代わりにa prepared statementを使用する必要があります。

それ以外は問題ありません。

3

クエリに文字列を埋め込む方法を除いて、コードは問題ありません。アドレスに引用符が含まれている場合、そのクエリは無効になります。これは問題のほんの一部です。このようにすることで、悪意のあるユーザーがクエリの意味を完全に変更するアドレスを入力できるSQLインジェクション攻撃の扉が開かれます。

必ずパラメータをバインドするために準備されたステートメントを使用します。

PreparedStatement stmt = connection.prepareStatement("SELECT Count(VideoID) from VIDEO WHERE Address=?"); 
stmt.setString(1, address); // proper escaping is done for you by the JDBC driver 
ResultSet rset = stmt.executeQuery(); 

また、あなたはあなたの結果セットと文を閉じるためにfinallyブロックを使用する必要があります。

+0

「文字列の埋め込み」では、バインディングは発生せず、パラメータもまったくありません。 –

+0

あなたはそうです。私は自分の投稿を編集します。 –

関連する問題