2015-10-10 152 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

これは実際のコードです...実行していますかポストグル? –

答えて

14

では、コンソールで直接SQLを書くとき、実際に間隔リテラルであるとみなされ、ワー​​ドINTERVALを以下の文字列リテラル文字列でない場合は動作しません有効です。

PostgreSQLのプリペアドステートメントは、サーバー側でPREPAREを使用して実装され、各?はサーバー上の実際の変数とみなされます。これはまた、$を書かなかったけれども、約$1の文句を言う理由です。

したがって、リテラル構文はプリペアドステートメントでは機能しません。

準備文の文字列表現(結果:println)があなたに混乱を与えないようにしてください。これは、サーバーには表示されません。サーバーはそこに変数を表示します。

したがって、文字列(変数またはリテラルになり得る)をとり、それを区間に変換する構文を使用する必要があります。例えば、?::INTERVALまたはCAST(? AS INTERVAL)です。

したがって、これはではなく、バグです。

+0

ありがとう! これは、私が購入した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(); 

...これを回避するために汚いハックを考えましたか?構文INTERVAL '30 minutes'ものの

関連する問題