2011-06-21 27 views
6

我有以下的JDBC代碼。請注意,我嘗試使用PostGIS的地理:PreparedStatement沒有讀取我所有的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代碼中工作而必須更改的內容。有任何想法嗎?

回答

8

您的問題是這樣的:

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

是一個SQL字符串文字,只是恰好包含8問號。由於這是一個SQL字符串,所以它裏面的問號都不被認爲是佔位符。這給你留下了兩個佔位符:VALUES列表最開始的那個佔位符,最後一個佔位符。

您必須以其他方式構建多邊形。有可能比ST_GeographyFromText更好,但是,唉,我不知道它是什麼,我沒有在任何地方設置PostGIS。如果必要的話,你可以手工用標準的字符串建立多邊形串扯皮,然後使用它的佔位符:

VALUES (?, ST_GeographyFromText(?), ?) 

ST_GeographyFromText佔位符會被看作是一個佔位符,因爲它不是一個字符串字母和你可以使用stmt.setString來給它一個值。

+0

啊,我明白了。感謝您提供非常明確的解釋。我很感激。 – Steph

6

由於畝太短正確地說問題在於引號內部沒有識別佔位符。

如果在Java中構建整個字符串是不可能的(例如,在我的情況下這太侵入),您可以通過在文字外移動佔位符,然後使用PgSQL字符串連接運算符來解決該問題,如下所示:

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

在你的情況下,解決辦法是:

ST_GeographyFromText('POLYGON((' || ? || ' ' || ? || ', ' || ? || ' ' || ? || 
    ', ' || ? || ' ' || ? || ', ' || ? || '' || ? || '))') 

不是很可讀,但它的工作原理...