質問編集履歴
2
パッケージ名クラス名の編纂
title
CHANGED
File without changes
|
body
CHANGED
@@ -71,7 +71,7 @@
|
|
71
71
|
ベタSQLだと上のようになりますが、チェック対象とするテーブル群はロジックでまた別のListにつめてるのでこれもmybatis上ではforeachします。このクエリの結果をうけて、Listの中には```existTable```がtrueだったものの```relname```をつめていきます(pg_classからとってきてるので余計なテーブル名も抽出されますが、```case when```で名前を指定しているもの以外はtrueになりません)。あとはそのListを使って目的のSQLでUNIONを行います。
|
72
72
|
```XML
|
73
73
|
<!-- 対象のテーブル名でテーブル存在チェックをおこなう -->
|
74
|
-
<select id="existTable" resultType="
|
74
|
+
<select id="existTable" resultType="package.DTO">
|
75
75
|
SELECT relname,
|
76
76
|
CASE WHEN
|
77
77
|
<foreach item="target" collection="targetList" separator=" WHEN ">
|
1
解決のメモ
title
CHANGED
File without changes
|
body
CHANGED
@@ -44,4 +44,59 @@
|
|
44
44
|
|
45
45
|
実現しようとしている、「指定した名前のテーブルが存在していたら```UNION ALL```して抽出するが、なければ無視して抽出する」を叶えるSQLについて、上記の方向性で問題なければ文法について、上記では無理であれば何を利用したらよいか方向性(CASE式など?)をご教示いただけませんでしょうか。
|
46
46
|
|
47
|
-
実際にはORMapperを使って動的SQLとして生成したものを使いますが、可能ならばプログラムにテーブル有無チェックのようなロジックを持たせるのは避けたいと思っています。
|
47
|
+
実際にはORMapperを使って動的SQLとして生成したものを使いますが、可能ならばプログラムにテーブル有無チェックのようなロジックを持たせるのは避けたいと思っています。
|
48
|
+
|
49
|
+
---
|
50
|
+
(当質問は[#39274](https://teratail.com/questions/39274)からの続きです)
|
51
|
+
遅くなりましたがやりたいことの実現ができたので備忘録を兼ねて以下に記載します。
|
52
|
+
すぐ上で
|
53
|
+
> 可能ならばプログラムにテーブル有無チェックのようなロジックを持たせるのは避けたいと思っています。
|
54
|
+
|
55
|
+
という夢をもっていましたが、[masuda_yuya](https://teratail.com/users/masuda_yuya)さんにご回答いただいたとおりSQLで一挙にまかなうのは無理のようでしたので、存在チェック用のクエリを投げて、その結果存在するテーブル名をリスト(```List<String>```)に詰めて、そのリストをmybatisのforeachで回してUNIONという風にしました。新しく実装するのは、
|
56
|
+
- テーブル存在チェックSQL
|
57
|
+
- テーブル存在チェックSQLのDTO
|
58
|
+
|
59
|
+
としました。
|
60
|
+
```SQL
|
61
|
+
select relname,
|
62
|
+
case
|
63
|
+
when relname='存在チェックしたいテーブル名1' then true
|
64
|
+
when relname='存在チェックしたいテーブル名2' then true
|
65
|
+
when relname='存在チェックしたいテーブル名3' then true
|
66
|
+
when relname='存在チェックしたいテーブル名4' then true
|
67
|
+
else false
|
68
|
+
end as existTable
|
69
|
+
from pg_class where relkind='r'
|
70
|
+
```
|
71
|
+
ベタSQLだと上のようになりますが、チェック対象とするテーブル群はロジックでまた別のListにつめてるのでこれもmybatis上ではforeachします。このクエリの結果をうけて、Listの中には```existTable```がtrueだったものの```relname```をつめていきます(pg_classからとってきてるので余計なテーブル名も抽出されますが、```case when```で名前を指定しているもの以外はtrueになりません)。あとはそのListを使って目的のSQLでUNIONを行います。
|
72
|
+
```XML
|
73
|
+
<!-- 対象のテーブル名でテーブル存在チェックをおこなう -->
|
74
|
+
<select id="existTable" resultType="sso.repository.ExistTableDTO">
|
75
|
+
SELECT relname,
|
76
|
+
CASE WHEN
|
77
|
+
<foreach item="target" collection="targetList" separator=" WHEN ">
|
78
|
+
relname=#{target} THEN true
|
79
|
+
</foreach>
|
80
|
+
ELSE false
|
81
|
+
END AS existTable
|
82
|
+
FROM pg_class where relkind='r'
|
83
|
+
</select>
|
84
|
+
```
|
85
|
+
↓
|
86
|
+
```XML
|
87
|
+
<!-- 存在したテーブルはUNIONする -->
|
88
|
+
<select id="hogehoge" resultType="package.DTO">
|
89
|
+
SELECT
|
90
|
+
* FROM
|
91
|
+
(
|
92
|
+
SELECT * FROM basetable
|
93
|
+
<foreach item="existTable" collection="existTableList" separator=" ">
|
94
|
+
UNION ALL SELECT * FROM ${existTable}
|
95
|
+
</foreach>
|
96
|
+
) tables
|
97
|
+
<where>
|
98
|
+
<!-- 適宜条件 -->
|
99
|
+
</where>
|
100
|
+
</select>
|
101
|
+
```
|
102
|
+
説明がいつにもまして雑ですが、同じことで行き詰った人の一助となれば幸いです。
|