teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

2

パッケージ名クラス名の編纂

2016/07/14 07:43

投稿

poyopi
poyopi

スコア115

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="sso.repository.ExistTableDTO">
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

解決のメモ

2016/07/14 07:43

投稿

poyopi
poyopi

スコア115

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
+ 説明がいつにもまして雑ですが、同じことで行き詰った人の一助となれば幸いです。