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です
一般的な解決策は、これを次のように表現することです。
interval '1 day' * ?
数値のプレースホルダーとして?
を使用します(小数部を使用する場合があります)。
SQL文法の場合、式interval '1 day'
全体が定数であるため、質問で試行された構文は拒否されます。プレースホルダーを挿入して変更することはできません。これは、3.?
を記述して、PI番号を形成する外部パラメーターとして.1415926
を渡すことができなかったのと同じです。