親バカエンジニアのナレッジ帳

webのエンジニアをやっており、日頃の開発で詰まったことや書き残しておきたいことを載せています。

Spring Data JPAでパラメータ以外でコロンを使いたい


RepositoryにSQLを直接記入

Spring Data JPAでORマッパーでは書けないようなSQLを実行したい場合、Repositoryに直接構文を書きますよね。
そんな時、パラメータで変数の値を渡したい時はコロンで変数を指定しますよね。
例えば以下のidのように

@Query(value = "SELECT * FROM test_tables WHERE id = :id ", nativeQuery = true)
List<Test> findById(@Param("id") Integer id);

パラメータ以外でコロンを使いたい

パラメータで変数を渡したい場合は普通にコロンをつければいいですが、それ以外の用途でコロンをつけたい場合はそうはいきません。
例えば以下のようなSQLをそのまま書くと、以下のようなエラーが発生します。
プログラムの中でこのようなSQLを実行する人はいないと思いますが笑、1から50まで表示されるSQLです。

SELECT 0 generate_series FROM DUAL WHERE (@num:= 1 - 1) * 0 UNION ALL
SELECT @num:= @num + 1 FROM information_schema.COLUMNS LIMIT 50

Repositoryに入れるとこんな感じですね。

@Query(value = "SELECT 0 generate_series FROM DUAL WHERE (@num:= 1 - 1) * 0 UNION ALL " +
"SELECT @num:= @num + 1 FROM information_schema.COLUMNS LIMIT 50", nativeQuery = true)
List<Integer> getNumber50();


エラー内容は以下です。

Space is not allowed after parameter prefix ‘:'



解決方法はエスケープ

上記エラーの解決方法としては、コロンの前にエスケープのスラッシュを入れることです。
ただし1つ入れるだけではダメで、以下のように2つのスラッシュを入れましょう。

@Query(value = "SELECT 0 generate_series FROM DUAL WHERE (@num\\:= 1 - 1) * 0 UNION ALL " +
"SELECT @num\\:= @num + 1 FROM information_schema.COLUMNS LIMIT 50", nativeQuery = true)
List<Integer> getNumber50();


Fire TV Stick

Fire TV Stick

新登場  Fire TV Stick 4K - Alexa対応音声認識リモコン付属

新登場 Fire TV Stick 4K - Alexa対応音声認識リモコン付属

Fire HD 10 タブレット (10インチHDディスプレイ) 64GB

Fire HD 10 タブレット (10インチHDディスプレイ) 64GB