我正在尝试将PostgreSQL与java代码一起使用以创建Web服务,但是我一直遇到相同的错误:
org.postgresql.util.PSQLException: ERROR: syntax error at or near "CA8E6"
Position : 84
下面是调用查询的函数:
public ArrayList<Position> TrajectoireH(String icao, String date_deb, String date_fin) {
query = "SELECT reception_date,longitude,latitude"
+ " FROM adsb_message"
+ " WHERE mode_s_icao_id = " + icao
+ " AND reception_date > " + date_deb
+ " AND reception_date < " + date_fin;
System.out.println(query);
Avion av = new Avion(icao);
Statement state;
try {
state = PostgreSQLConnection.getConnection().createStatement();
ResultSet result = state.executeQuery(query);
while(result.next()) {
float lat,lon;
String date;
lat = result.getFloat("latitude");
lon = result.getFloat("longitude");
date = result.getString("reception_date");
Position pos = new Position(lat,lon,date);
av.ajoutPos(pos);
}
} catch (SQLException e) {
e.printStackTrace();
}
//ResultSetMetaData resultMeta = result.getMetaData();
return av.getTrajectoireH();
}
为了进行测试,我选择了国际民航组织"4CA8E6"。似乎该程序在第一个字符处停止阅读国际民航组织。打印查询返回:
SELECT reception_date,longitude,latitude FROM adsb_message
WHERE mode_s_icao_id = 4CA8E6
AND reception_date > 2000-01-01 00:00:00.0
AND reception_date < 3000-01-01 00:00:00.0
这对我来说似乎是正确的。你知道语法错误可能来自哪里吗?
错误的直接原因是显而易见的,因为原始查询中包含未转义的字符串和日期文字。 最好的解决方法是使用预准备语句,如下所示。 请注意,我将变量date_feb
和date_fin
绑定为字符串,而实际上最佳实践是绑定某种兼容的 Java 日期类型(例如 java.util.Date
或者可能是Java 8 API中的内容(。 如果数据库接受绑定字符串文本,则绑定字符串文本可能会起作用。 我还没有纠正这一点,因为很可能你的 Java 代码中已经有日期变量了,你只需要开始使用它们。
String query = "SELECT reception_date,longitude,latitude"
+ " FROM adsb_message"
+ " WHERE mode_s_icao_id = ?"
+ " AND reception_date > ?"
+ " AND reception_date < ?";
PreparedStatement ps = PostgreSQLConnection.getConnection().prepareStatement(query);
ps.setString(1, icao);
ps.setString(2, date_feb);
ps.setString(3, date_fin);
ResultSet result = ps.executeQuery();
while (result.next()) {
float lat, lon;
String date;
lat = result.getFloat("latitude");
lon = result.getFloat("longitude");
date = result.getString("reception_date");
Position pos = new Position(lat,lon,date);
av.ajoutPos(pos);
}
SELECT
reception_date,
longitude,
latitude
FROM adsb_message
WHERE
mode_s_icao_id = '4CA8E6'
AND reception_date > '2000-01-01 00:00:00.0'
AND reception_date < '3000-01-01 00:00:00.0'