12

データベースに特定の値が既に存在するかどうかを確認しようとしています。JDBCを使用してJavaスタンドアロンアプリからデータベースにアクセスしています(レコードをdbに挿入するためのクエリが機能するため、セットアップと接続は問題ありません)。

String queryCheck = "SELECT * from messages WHERE msgid = " + msgid;
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(queryCheck); // execute the query, and get a java resultset

// if this ID already exists, we quit
if(rs.absolute(1)) {
     conn.close();
     return;
}

次のエラーが表示されます (SQL 構文に問題があるようです):

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 'd-f05708071f8f' at line 1

ただし、MySQL コマンド ラインでこのコマンドを実行しようとすると、うまくいきます。私の発言の何が問題なのか教えてもらえますか? ヒントをありがとう!

4

7 に答える 7

26

StringMySQL ではaを引用符で囲む必要があるため、クエリは

SELECT * from messages WHERE msgid = 'd-f05708071f8f';

いいえ

SELECT * from messages WHERE msgid = d-f05708071f8f;

したがって、コードは次のようになります

String queryCheck = "SELECT * from messages WHERE msgid = '" + msgid + "'";

PreparedStatementこのような問題や SQL インジェクションのリスクを回避するために、 を使用することをお勧めします。

final String queryCheck = "SELECT * from messages WHERE msgid = ?";
final PreparedStatement ps = conn.prepareStatement(queryCheck);
ps.setString(1, msgid);
final ResultSet resultSet = ps.executeQuery();

クエリの作成に文字列連結を使用することは、非常に悪い習慣と見なされます。久しぶりです。

さらに、これははるかに少ないデータを返し (のサイズを考えてください)、MySQL もそれを最適化できるためselect count(*)、完全ではなく使用することをお勧めします。select *ResultSet

final String queryCheck = "SELECT count(*) from messages WHERE msgid = ?";
final PreparedStatement ps = conn.prepareStatement(queryCheck);
ps.setString(1, msgid);
final ResultSet resultSet = ps.executeQuery();
if(resultSet.next()) {
    final int count = resultSet.getInt(1);
}
于 2013-04-19T07:26:08.440 に答える
6

バインド変数を使用する必要があります。

 PreparedStatement st = conn.prepareStatement(
    "SELECT * from messages WHERE msgid = ?");
 st.setString(1, msgid);
 ResultSet rs = st.executeQuery(queryCheck); 

または、手動で引用することもできますが、それは危険です。

SQL インジェクションの防止に加えて、同じクエリを繰り返し実行する場合、準備済みステートメントはパフォーマンスも向上させるはずです。

于 2013-04-19T07:26:15.073 に答える
3

msgid は varchar であるため、where 句の値を一重引用符で囲む必要があります。

String queryCheck = "SELECT * from messages WHERE msgid = '" + msgid + "'";

ただし、SQL 文字列を動的に生成することはお勧めできません。アプリケーションが SQL インジェクションにさらされる可能性があるためです。

代わりに次を使用しますPreparedStatement

            String queryCheck = "SELECT * from messages WHERE msgid = ?";
            PreparedStatement st = conn.prepareStatement(queryCheck);
            st.setString(1, msgid);
            ResultSet rs = st.executeQuery();
于 2013-04-19T07:26:08.000 に答える
3

パラメータを一重引用符で囲みます。

"SELECT * FROM messages WHERE msgid = '" + msgid + "'";

または、準備済みステートメントを使用することをお勧めします。

于 2013-04-19T07:26:15.140 に答える
3

これを試すことができます:

String queryCheck = "SELECT * from messages WHERE msgid = '" + msgid + "'";

msgid を引用符で囲みませんでした。(私は、msgidは値Stringではなく、Integer値であると想定しています。)

于 2013-04-19T07:27:36.097 に答える
1

一重引用符を使用する必要があります

SELECT * from messages WHERE msgid = 'd-f05708071f8f'; 
于 2013-04-19T07:27:02.153 に答える
0
String sql1 ="SELECT Time FROM monday_wednesday WHERE Time ='"+time.getSelectedItem()+"'";
pst=con.prepareStatement(sql1);
rs=pst.executeQuery();
if(rs.next()) {
    if(rs.getString("Time").equals(time.getSelectedItem())) {
        JOptionPane.showMessageDialog(null,"Time is already taken","",JOptionPane.INFORMATION_MESSAGE); 
    }
} else {
    String sql="INSERT INTO monday_wednesday(pfname,pmname,plname,Birthdate,Gender,Address,City,Contact,Contactperson,Time,Date)\n" + "VALUES ('"+txtFirstName1.getText()+"','"+txtMiddleName1.getText()+"','"+txtLastName1.getText()+"','"+d+"','"+gender.getSelectedItem()+"','"+ txtAddress.getText()+"','"+txtCity.getText()+"','"+txtContact.getText()+"','"+txtContactPerson1.getText()+"','"+time.getSelectedItem()+"','"+dateFormat.format(date)+"')";
}

単純な重複エントリ アルゴリズム

于 2017-07-29T16:30:45.860 に答える