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(Unknown Source) 在 sun.jdbc.odbc.JdbcOdbc.standardError(Unknown Source) 在 sun.jdbc.odbc.JdbcOdbc.SQLPrepare(Unknown Source) 在 sun.jdbc.odbc.JdbcOdbcConnection .prepareStatement(Unknown Source) at sun.jdbc.odbc.JdbcOdbcConnection.prepareStatement(Unknown Source) at PostMessage.addMessageToDatabase(PostMessage.java:118) at PostMessage.doPost(PostMessage.java:55) at 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 语句,您可以简化查询和构建字符串。

附带说明一下,这可能都是在 scriptlet (<%%>) 标记内完成的,这不是一个好习惯。您可能希望将此代码移动到后端 java 类。

编辑- 看到您的下一个错误后,我打开 Access 来测试查询。您的原始查询存在以下问题:您的内部选择周围有一组额外的单引号。

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

选择周围的那组额外的单引号会导致缺少运算符异常。如果您删除这些内容,那么您会从我的查询中得到错误。所以这两个查询几乎相同。

此查询可以与另一个数据库(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

我会尝试改变

'(从用户 WHERE 用户名中选择 ID = '" + uName + "')'

CSTR(从用户选择 ID WHERE 用户名 = '" + uName + "')

于 2012-09-19T13:38:35.380 回答
0

内部查询

从用户那里选择 ID 用户名 = '" + uName + "'

应该只返回一个值,我认为您在 User 表中有多个记录 UserName hrai,这会为您的代码的执行造成问题。

确保此查询仅返回一条记录(仅返回一个值)

尝试使用Distinct进行 beloq 查询

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

但它仍然应该只从这个查询返回一个值

于 2012-09-20T08:31:59.007 回答