0

jsp を使用して ms access データベースにデータを挿入しようとしていますが、SQLException が表示されます。クエリにはサブクエリがあります。 アクセスでクエリを実行しようとしましたが、クエリは正常に実行されます。jsp が例外をスローする理由がわかりません。クエリを 3 時間何度も何度もチェックしましたが、まだ役に立ちません。誰か助けてくれませんか??

    try {
        Class.forName("sun.jdbc.odbc.JdbcOdbcDriver").newInstance();

        //Creating new statement
        Connection conn = DriverManager.getConnection("jdbc:odbc:accdbJava");

        String uName = ((UserInfo) session.getAttribute("userInfo")).getUserName().trim();

        //Creating statement
        PreparedStatement stmt = conn.prepareStatement("INSERT INTO Message (User_ID, Heading, Body, DatePosted) VALUES ('(SELECT ID FROM User WHERE UserName = '" + uName + "')', '" + messageItem1.getSubject() + "', '" + messageItem1.getMessage() + "', '" + messageItem1.getDatePosted() + "');");

        //Executing the update
        stmt.executeUpdate();

        //Closing connection, statement
        stmt.close();
        conn.close();
    }
    catch(Exception e) {
        e.printStackTrace();
    }

例外は次のとおりです。

*java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver] クエリ式 ''(SELECT ID FROM User WHERE UserName = 'hrai')'' の構文エラー (演算子がありません)。sun.jdbc.odbc.JdbcOdbc.createSQLException (未知のソース) で sun.jdbc.odbc.JdbcOdbc.standardError (未知のソース) で sun.jdbc.odbc.JdbcOdbc.SQLPrepare (未知のソース) で sun.jdbc.odbc.JdbcOdbcConnection .prepareStatement (不明なソース) の sun.jdbc.odbc.JdbcOdbcConnection.prepareStatement (不明なソース) の PostMessage.addMessageToDatabase(PostMessage.java:118) の PostMessage.doPost(PostMessage.java:55) の javax.servlet.http.HttpServlet org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.

4

3 に答える 3

1

次の変更を試してください

これは、Access 以外のデータベースでも機能することに注意してください。アクセスについては、以下の編集を参照してください。

String SQLQuery = "INSERT INTO Message (User_ID, Heading, Body, DatePosted) " +
          "VALUES ((SELECT ID FROM USER WHERE username=?), ?, ?, ?)";

PreparedStatement stmt = conn.prepareStatement(SQLQuery);
stmt.setString(1, uName);
stmt.setString(2, messageItem1.getSubject());
stmt.setString(3,messageItem1.getMessage());
stmt.setDate(4,messageItem1.getDatePosted());

クエリの最後にセミコロンは必要ありません。Prepared ステートメントを適切に使用することで、クエリと文字列の作成を簡素化できます。

余談ですが、これはおそらくすべてスクリプトレット (<%%>) タグ内で行われているため、適切な方法ではありません。このコードをバックエンド Java クラスに移動することができます。

編集- 次のエラーを確認した後、Access を開いてクエリをテストしました。元のクエリには、内側の選択を一重引用符で囲むという問題があります。

Values ('(SELECT ID FROM User WHERE UserName = 'foo')'...

選択を囲む余分な一重引用符のセットは、欠落している演算子の例外を与えます。それらを削除すると、クエリからエラーが発生します。したがって、2 つのクエリはほぼ同じです。

このクエリは別のデータベース (MySQL、SQL Server など) でも機能しますが、Access はすべての SQL ルールに従っていないため、多少のヒットやミスが発生することがあります。

元の回答に次の変更を加えて、挿入を実行してみてください

String SQLQuery = "INSERT INTO MESSAGE (User_ID, Heading, Body, DatePosted) " +
    "SELECT ID, ?, ?, ? " + 
    "FROM USER " + 
    "WHERE username=?";

PreparedStatement stmt = conn.prepareStatement(SQLQuery);

stmt.setString(1, messageItem1.getSubject());
stmt.setString(2,messageItem1.getMessage());
stmt.setDate(3,messageItem1.getDatePosted());
stmt.setString(4, uName);

いくつかの引数を移動したことに注意してください。また、使用されている VALUES キーワードはありません。このクエリはAccessでうまくいきました

于 2012-09-19T15:03:20.410 に答える
0

私は変えようとするだろう

'(SELECT ID FROM User WHERE UserName = '" + uName + "')'

CSTR(SELECT ID FROM User WHERE UserName = '" + uName + "')

于 2012-09-19T13:38:35.380 に答える
0

内部クエリ

SELECT ID FROM User WHERE UserName = '" + uName + "'

1 つの値のみを返す必要があります。UserName hrai の User テーブルに複数のレコードがあり、コードの実行に問題が発生していると思います。

このクエリが 1 つのレコードのみを返すことを確認してください (1 つの値のみ)。

Distinctを使用して beloq クエリを試す

SELECT Distinct(ID) FROM User WHERE UserName = '" + uName + "'

ただし、このクエリから返される値は 1 つだけである必要があります

于 2012-09-20T08:31:59.007 に答える