我正在尝试使用jsp在ms访问数据库中 INSERT 某些数据,但它显示了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驱动程序]查询表达式中的语法错误(缺少运算符)''(SELECT ID FROM User WHERE UserName ='hrai')''。 at sun.jdbc.odbc.JdbcOdbc.createSQLException(Unknown Source) at sun.jdbc.odbc.JdbcOdbc.standardError(Unknown Source) at sun.jdbc.odbc.JdbcOdbc.SQLPrepare(Unknown Source) at sun.jdbc.odbc.JdbcOdbcConnection.prepareStatement(Unknown Source) at sun.jdbc.odbc.JdbcOdbcConnection.prepareStatement(Unknown Source) 在PostMessage.addMessageToDatabase(PostMessage.java:118) 在PostMessage.doPost(PostMessage.java:55) 在javax.servlet.http.HttpServlet.service(HttpServlet.java:637) 在javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 在org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) 在org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 在org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) 在org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) 在org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 在org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298) 在org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857) 在org.apache.coyote.http11.Http11Protocol $ Http11ConnectionHandler.process(Http11Protocol.java:588) 在org.apache.tomcat.util.net.JIoEndpoint $ Worker.run(JIoEndpoint.java:489) 在java.lang.Thread.run(未知来源) *
答案 0 :(得分:1)
尝试以下更改
请注意,这适用于非Access数据库。 for 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 statement,您可以简化查询和构建字符串。
另外,这可能都是在scriptlet(< %%>)标记内完成的,这不是一个好习惯。您可能希望将此代码移动到后端java类。
编辑 - 看到下一个错误后,我打开了Access来测试查询。您的原始查询会遇到问题,即内部选择周围有一组额外的单引号。
Values ('(SELECT ID FROM User WHERE UserName = 'foo')'...
select周围的额外单引号集会给出缺少的运算符异常。如果你删除了那些,那么你从我的查询中得到错误。 所以两个查询几乎相同。
此查询可以与其他数据库(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
中适用于我答案 1 :(得分:0)
我会尝试改变
'(SELECT ID FROM User WHERE UserName ='“+ uName +”')'
到
CSTR(SELECT ID FROM User WHERE UserName ='“+ uName +”')
答案 2 :(得分:0)
内部查询
SELECT ID FROM User WHERE UserName ='“+ uName +”'
应该只返回一个值,我认为UserName中有多个记录用于UserName hrai,这会产生执行代码的问题。
确保此查询仅返回一条记录(仅一个值)
使用区别
尝试beloq查询SELECT Distinct(ID)FROM User WHERE UserName ='“+ uName +”'
但它仍然应该只有一个从此查询返回的值