2015-10-10 47 views
8

我得到這個PSQLException:

org.postgresql.util.PSQLException: ERROR: syntax error at or near "$1" 
    Position: 37 

當我運行下面的代碼:

ps = connection.prepareStatement("SELECT current_timestamp + INTERVAL ?;"); 
ps.setString(1, "30 minutes"); 
System.out.println(ps); 
rs = ps.executeQuery(); 

然而, println函數在控制檯中顯示:

SELECT current_timestamp + INTERVAL '30 minutes' 

任何人都知道什麼是錯的?控制檯中的查詢在pgAdmin中運行正常,所以我知道它不是語法錯誤。

+0

沒有什麼區別,分號完全有效 –

+0

該查詢適用於我,這是實際代碼還是你有任何變量來代替「30分鐘」 – silentprogrammer

+0

這是實際的代碼......你正在運行Postgres的? –

回答

14

雖然語法INTERVAL '30 minutes'是有效的,當你直接在控制檯寫SQL,它實際上是認爲是間隔字面並不會在哪裏工作後面的字INTERVAL字符串不是一個字符串。

PostgreSQL中的準備語句在服務器端使用PREPARE實現,每個?被視爲服務器上的實際變量。這也是爲什麼它會抱怨$1,儘管你從未在你的發言中寫過$

因此,文字語法不適用於預準備語句。

不要讓準備語句的字符串表示形式(println的結果)讓您感到困惑 - 這不是服務器看到的。服務器在那裏看到一個變量。

因此,您需要使用帶有字符串(可以是變量或文字)並將其轉換爲間隔的語法。例如?::INTERVALCAST(? AS INTERVAL)

因此這是而不是的一個錯誤。

+0

非常感謝! 'ps = connection.prepareStatement(「SELECT current_timestamp +?:: INTERVAL;」);' 這個按預期工作,遺憾的是這沒有記錄在我買來的JSP書中:) –

+0

嗯,這是一本JSP書,而不是PostgreSQL的,我想。每個DBMS都有自己的怪癖,有些與它決定實施JDBC合同的具體方式有關。 – RealSkeptic

+0

非常好的一點確實...當某些事情不能正常工作時,我總是很快地指點哈哈 –

-1

我相信這是一個Postgres的錯誤,所以我想到了一個骯髒的黑客來解決這個問題的......

ps = connection.prepareStatement("SELECT current_timestamp + INTERVAL ?;"); 
ps.setString(1, "30 minutes"); 
ps = connection.prepareStatement(ps.toString()); 
rs = ps.executeQuery(); 

我不知道這是否會永遠得到解決嗎?

相關問題