在Eclipse中使用PostgreSQL时如何定位语法错误位置
问题描述
在Eclipse中使用PostgreSQL执行SQL代码时触发报错:
syntax error at end of input position 13
我写了近200行代码,不觉得错误出在代码的第13行,完全不知道该怎么定位这个报错的实际位置!
相关代码片段如下:
String query = "SELECT * FROM BRANCH"; ResultSet rs = executeQuery(connection, query); try { while (rs.next()) { System.out.println("Column 1 returned"); System.out.println(rs.getString(1)); } } catch (SQLException e) { e.printStackTrace(); } rs.close(); dropTable(connection, " delayedFlights"); createTable(connection," delayedFlights( ID_of_Delayed_Flight int pr" + "imary key, month int, dayOfMonth int, dayOfWeek int, depTime int, scheduledDeptTime int, arrTime int, " + "scheduledArrTime int, uniqueCarrier varchar(5), flightNum int, actualFlightTime int, scheduledFlightTime int," + "airTime int, arrDelay int, depDelay int, orig varchar(5), dest varchar(5), distance int);"); int rows = insertIntoTableFromFile(connection, "delayedFlights", "src/delayedFlights.txt"); System.out.println(rows + " rows inserted."); dropTable(connection, " airport"); createTable(connection, " airport( airportCode int primary key, airportName varchar(20), city varchar(25)," + "state varchar(25));"); int rows2 = insertIntoTableFromFile(connection, "airport", "src/airport.txt"); System.out.println(rows2 + " rows inserted.");
问题分析与解决
1. 先搞懂报错里的position含义
PostgreSQL报错里的position 13指的是它实际接收到的SQL语句里的第13个字符,不是你Java代码的行号。要定位问题,最有效的办法是:
- 在
executeQuery、dropTable、createTable这些执行SQL的方法内部,把最终要执行的完整SQL语句打印出来; - 或者在调用这些方法前,直接输出拼接好的SQL字符串到控制台,这样就能看到PostgreSQL真正处理的SQL是什么,再对应position 13找语法错误。
2. 代码里的明显问题
从给出的片段看,有几个会直接导致SQL语法错误的点:
- 表名带前导空格:比如
" delayedFlights"和" airport",这些空格会被PostgreSQL当成表名的一部分,不仅执行DROP TABLE时可能找不到表,后续createTable用带空格的表名,和插入时用的无空格表名"delayedFlights"/"airport"不一致,会导致一系列找不到表的错误; - 资源关闭不规范:
rs.close()直接放在try块外面,如果查询失败导致rs为null,会触发空指针异常,应该把资源关闭逻辑放到finally块,或者用try-with-resources自动管理; - SQL拼接需检查:第一个createTable的字符串拼接把
primary拆成了pr+imary,虽然拼接后没问题,但要确保所有拼接的SQL片段没有拼写错误或遗漏。
3. 具体修复步骤
- 去掉所有表名前后的空格:把
" delayedFlights"改成"delayedFlights"," airport"改成"airport",保证所有操作的表名完全一致; - 打印执行的SQL:修改
dropTable和createTable方法,执行前输出SQL,比如:public void dropTable(Connection conn, String tableName) throws SQLException { String sql = "DROP TABLE IF EXISTS " + tableName; System.out.println("执行SQL:" + sql); try (Statement stmt = conn.createStatement()) { stmt.execute(sql); } } - 用try-with-resources管理数据库资源:避免空指针和资源泄漏,重构查询代码:
String query = "SELECT * FROM BRANCH"; try (Statement stmt = connection.createStatement(); ResultSet rs = stmt.executeQuery(query)) { while (rs.next()) { System.out.println("Column 1 returned"); System.out.println(rs.getString(1)); } } catch (SQLException e) { e.printStackTrace(); }
内容的提问来源于stack exchange,提问作者Elephants unite
相关产品推荐
相关产品推荐

