web-dev-qa-db-ja.com

postgresqlでpreparestatementsを使用した構文エラー

JavaアプリケーションがPostgreSQLデータベースに接続しています。

次のような簡単なコードを使用します。

        ps = con.prepareStatement(sql);
        if (dataTypes != null && dataTypes.size() > 0) {
            for (int i = 0; i < dataTypes.size(); ++i) {
                if (dataTypes.get(i) == DataTypes.NUMERIC)
                    ps.setLong((i + 1), Long.parseLong(values.get(i)));
                else
                    ps.setString((i + 1), values.get(i));
            }
        }
        rs = ps.executeQuery();

のようなクエリで

select ? from dummy

正常に動作します。 postgresのログに表示される内容は次のとおりです。

2015-06-13 12:48:30 EEST [28294-3] xx LOG:  execute <unnamed>: select $1 from dummy
2015-06-13 12:48:30 EEST [28294-4] xx DETAIL:  parameters: $1 = '0'

しかし、次のようなクエリでは:

select to_char(now()+interval ? day, 'YYYYMMDD') from dummy

構文エラーが発生します:

Cause [org.postgresql.util.PSQLException: ERROR: syntax error at or near "$1"

そしてpostgresのログでは:

2015-06-13 13:17:39 EEST [29311-3] xxx ERROR:  syntax error at or near "$1" at character 31
2015-06-13 13:17:39 EEST [29311-4] xxx STATEMENT:  select to_char(now()+interval $1 day, 'YYYYMMDD') from dummy

しかしpgadminでは次のようなもの

select to_char(now()+interval '0' day, 'YYYYMMDD') from dummy

エラーなしで問題なく動作します。

何が問題なのかわからない。クエリの1つは機能するが、他のクエリは機能しないのはなぜですか?

私のPostgreSQLバージョンは9.4です

1
alpert

一般的な解決策は、これを次のように表現することです。

interval '1 day' * ?

数値のプレースホルダーとして?を使用します(小数部を使用する場合があります)。

SQL文法の場合、式interval '1 day'全体が定数であるため、質問で試行された構文は拒否されます。プレースホルダーを挿入して変更することはできません。これは、3.?を記述して、PI番号を形成する外部パラメーターとして.1415926を渡すことができなかったのと同じです。

4
Daniel Vérité