PreparedStatement未读取我所有的PostGIS Geography参数

6

我有以下的JDBC代码。请注意,我尝试使用PostGIS地理信息:

PreparedStatement stmt = db.prepareStatement("INSERT INTO " +
                    "source_imagery (image_path, boundary, image_time)" +
                    " VALUES (?, ST_GeographyFromText('POLYGON((" +
                    "? ?, ? ?, ? ?, ? ?))'), ?)");

            stmt.setString(1, file.getAbsolutePath());
            stmt.setDouble(2, bounds.getY());
            stmt.setDouble(3, bounds.getX());
            ...

在代码的最后一行,我遇到了以下异常:

org.postgresql.util.PSQLException: The column index is out of range: 3, number of columns: 2.

我知道它认为我只有2个参数,但你可以看到我打算有10个。我不确定为什么它没有读取POLYGON中的任何参数。我知道如果我直接在数据库中使用这个SQL语句是有效的,但我不确定我需要改变什么才能让它在我的Java代码中工作。有什么想法吗?

2个回答

9

您的问题在于这个:

'POLYGON((? ?, ? ?, ? ?, ? ?))'

是一个SQL字符串字面量,恰好包含八个问号。由于它是一个SQL字符串字面量,其中的所有问号都不被视为占位符。这只留下了两个占位符:一个在VALUES列表的开头,另一个在结尾。

你将不得不以其他方式构建你的多边形。可能有比ST_GeographyFromText更好的方法,但是我不知道它是什么,也没有在任何地方设置PostGIS。如果需要,您可以手动使用标准字符串处理构建POLYGON字符串,然后为其使用占位符:

VALUES (?, ST_GeographyFromText(?), ?)

ST_GeographyFromText 中的占位符不会被视为字符串文字内的占位符,因此您可以使用 stmt.setString 为其赋值。


啊,我明白了。非常感谢你清晰的解释。我很感激。 - Steph
1
由于我需要ST_DISTANCE,但上述方法不起作用(错误:函数st_distance(character varying)不存在),所以我按照这个答案中通常建议的方式操作了字符串,像这样操纵字符串:String sqlFetchMgq = select ... ST_DISTANCE(coordinates, 'SRID=4326;POINT(%s %s)'),然后使用sqlFetchMgq = String.format(sqlFetchMgq, longitude, latitude);我成功了! - oupoup

6

正如mu is too short所说,问题在于引号内部未识别占位符。

如果无法在Java中构建整个字符串(例如,在我的情况下,这样做会过于侵入性),您可以通过将占位符移到文字外部,然后使用PgSQL字符串连接运算符来解决该问题,就像这样:

ST_GeographyFromText('SRID=4326;POINT(' || ? || ' ' || ? || ')')

在您的情况下,解决方案如下:
ST_GeographyFromText('POLYGON((' || ? || ' ' || ? || ', ' || ? || ' ' || ? ||
    ', ' || ? || ' ' || ? || ', ' || ? || '' || ? || '))')

虽然不太易读,但它确实有效...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接