Union利用時のspecify()について

204 views
Skip to first unread message

toshi sugi

unread,
Dec 1, 2010, 10:00:12 PM12/1/10
to DBFluteユーザの集い
いつもお世話になっております。

sqlserver2005にてdbflute0.9.4を利用していて不可思議な事象に出会いましたので、
質問をさせてください。

結論から言うと、UNION+specifyの利用時にselectList,selectPageの挙動が違うかもしれません。

複数のテーブルをJOINしたVW_AAAというビューがあります。

このビューに対して、ステータスの値により複数のSQLを投げてその結果をUNIONでマージしようとしております。

A SELECT カラム1,カラム2,カラム3 FROM VW_AAA WHERE STATUS = 1
B SELECT カラム1,カラム2,カラム3 FROM VW_AAA WHERE STATUS = 2

この2つのSQLをUNION(重複は除きたい)し、結果を取得しようとしています。


VwAaaCB vwAaaCB = new VwAaaCB();
vwAaaCB.specify().columnNxxxxx1();
vwAaaCB.specify().columnNxxxxx2();
vwAaaCB.specify().columnNxxxxx3();
vwAaaCB.query().setStatus_Equals(1);

vwAaaCB.union(new UnionQuery<VwAaaCB>() {
public void query(VwAaaCB unionCB) {
unionCB.query().setStatus_Equals(2);
}
});

selectListはspecify()で指定したカラムを取得していますが、selectPageは全てのカラムを取得しようとしています。

よろしくお願いします。

toshi sugi

unread,
Dec 1, 2010, 10:42:06 PM12/1/10
to DBFluteユーザの集い

kubo

unread,
Dec 2, 2010, 6:27:02 AM12/2/10
to dbf...@googlegroups.com
jfluteです。

こんばんは、DBFlute ご利用ありがとうございます。

ひとまず、こちらで dbflute-sqlserver-example にてテストを
してみましたが再現しません。Exampleは最新版なので、
途中で何かしらの修正で一緒に直ったのかもしれません。
WxSQLServerUnionPagingTest が該当テストです。

SQLServer における Union と Paging は確かに特殊です。
と、書きながら思い出したのですが、DBFlute-0.9.6.1 にて
「(DBFLUTE-594){Java/C#}: SQLServerでCBのUnionとPagingの同時利用をサポート」
という対応をしています。つまり、それ以前のバージョンでは、
そもそも「CBのUnionとPagingの同時利用」がサポートされていません。
発行されているSQLは、どうなっていますでしょうか?
恐らく、top N 構文が正しく利用できていないのではないかと思います。

ということで、DBFlute-0.9.4 + SQLServer においては、
Union的な結果を取得するページング検索をする場合は、
外だしSQLでお願いします。
(OrScopeQuery も DBFlute-0.9.6.3 からとなりますので)
また、大変かもしれませんが、一応念のため、最新版に
アップグレードされることをお奨めしておきます。

とはいえ、SpecifyColumn が selectList() と selectPage() で
結果が違っていたというのは、ちょっと不明ですね。
ページングの特殊処理をしていないなら、違いが出そうに
思えないのですが...まあ、これはこちらの内部的な話です。

正直、Java版DBFlute と SQLServer を実務で利用するという話は、
ここ最近になって、ようやく耳に入った話でした。
(別件でも利用の話を聞きましたが、本当につい最近でした)
DBFlute.NET(C#版)では普通にありますし、DBFluteより前の時代では
Java版DBFlute と SQLServer の組み合わせはありましたが、
4年ほど全く聞かなかったので、どうしても細かい部分での対応が
後回しになってしまったという反省もあり、申し訳ないところです。
一方で、こういったフィードバックで利用データベースがわかるのは、
DBFluteの成長にプラスになることです。ありがとうございます。

2010/12/2 toshi sugi <merup...@gmail.com>:

> --
> このメールは Google グループのグループ「DBFluteユーザの集い」の登録者に送られています。
> このグループに投稿するには、dbf...@googlegroups.com にメールを送信してください。
> このグループから退会するには、dbflute+u...@googlegroups.com にメールを送信してください。
> 詳細については、http://groups.google.com/group/dbflute?hl=ja からこのグループにアクセスしてください。
>
>

toshi sugi

unread,
Dec 2, 2010, 9:16:09 PM12/2/10
to DBFluteユーザの集い
jflute様

早々のご対応ありがとうございます。

1点誤りがありました。
こちらで使用しているdbfluteは0.9.4ではなく、0.9.7.4でした。
申し訳ありません。

その上で、0.9.7.6にバージョンアップしてご提示されたテストケースを
実行してみました。
結果はグリーンで問題ありませんでした。

が、テストケースを問題が発生したビューに差し替えた瞬間に質問した現象が発生してしまいました。

その上でいろいろと調査をしていると、どうやらビューの中にTEXTカラムがあることが原因のようでした。

unionを実行する際に、TEXTカラムが混ざっていると、distinctができないため、
specify()で除去していたのですが、pagingSelectを実行しようとすると、
実データを取得する前にcount(*)で件数を取得しにいきます。
そのcount(*)のSQLでspecify()が効いていないようです。

ひとまず原因がわかったので、こちらの方ではビュー中にTEXTカラムを混ぜないように対処いたします。

ありがとうございました。
> 2010/12/2 toshi sugi <merupin0...@gmail.com>:

kubo

unread,
Dec 2, 2010, 10:58:08 PM12/2/10
to dbf...@googlegroups.com
jfluteです。

なるほど、TEXTカラムが混じってるので、
それを除去するための SpecifyColumn だったのですね。

specify()が効いていないと思われるcountのSQLは、
どのようなSQLになっていますでしょうか?
こちらで、TEXTカラムが入ったテーブルで
同じような状況のテストを実行したときに、
カウント検索の方は以下のようになっています。
インラインビューの中でカラム絞りが効いているため、
「TEXTカラムのdistinctできないエラー」は発生せずに
実行できました。

select count(*)
from (select dfloc.MEMBER_ID as c1, dfloc.WITHDRAWAL_DATETIME as c2
from MEMBER_WITHDRAWAL dfloc
union
select dfloc.MEMBER_ID as c1, dfloc.WITHDRAWAL_DATETIME as c2
from MEMBER_WITHDRAWAL dfloc
) dfmain

また、「効いていない」というのはどういう状況になりますでしょうか?

2010/12/3 toshi sugi <merup...@gmail.com>:

kubo

unread,
Dec 2, 2010, 11:13:38 PM12/2/10
to dbf...@googlegroups.com
jfluteです。

再現しました。SQLServerかどうかに関わらず、
「PKのないテーブルでの Union + {Paging のカウント検索のSQL}」
において、SpecifyColumn が効かないというバグでした。
で、ビューも「PKのないテーブル」に含まれるので、
そちらでも発生したというところですね。

additionalPrimaryKeyMap.dfprop にて回避はできますが、
DBFlute本体でも対応できるならしたいと思います。
(今、検討中です)

2010/12/3 kubo <dbf...@gmail.com>:

kubo

unread,
Dec 3, 2010, 12:49:21 AM12/3/10
to dbf...@googlegroups.com
jfluteです。

状況を説明しますと、

まず、Behavior.selectCount(cb)では、SpecifyColumn は無効で、
必ず、該当する条件に対して「ユニークなカウント」を取得するという
仕様があります。PKありテーブルはSpecify必須のPKがユニークなのですが、
PKなしテーブルはそうもいかないので、union の場合に全カラム列挙します。

そして、ページングのカウント検索が、上記のカウント検索と同じ仕様と
なっているため、今回の現象が発生してしまいました。
ページングの場合は「ユニークなカウント」ではなく「実データに合うカウント」
にする必要があるため、PKなしテーブルの UnionQuery & SpecifyColumn
ではその挙動に不具合があると言えます。PKなしテーブルはそもそも非推奨なので、
そこに制限はあってもいいのですが、ビューはそうもいかないですね。
まず、これは直します。toshi さんの今回現象はこれが対応されれば、
解決するはずです。
もちろん、ビューでtext型のカラムを業務的に外せるのであれば、
DBFluteの機能以前にそれに越したことはないのです。

ついでに、Behavior.selectCount(cb)においては、
PKなしテーブルでの UnionQuery & SpecifyColumn したときに、
「text型カラムで union できないから SpecifyColumn で回避する」
っていう技は、今回の対応前も対応後もやはりできません。
PKなしテーブルは非推奨による制限、ビューはできるだけdfpropでPK付ける、
という運用にするか悩ましいところですね...
(「ユニークなカウント」という仕様を取り下げると一貫性がなくなってしまう...)

しばし、お待ち下さい。

kubo

unread,
Dec 3, 2010, 3:59:28 AM12/3/10
to dbf...@googlegroups.com
jfluteです。

DBFlute-0.9.7.7-02-SNAPSHOT にて反映しました。
(モジュール、ランタイム両方)
dbflute-sqlserver-example でも反映させてテストしています。
もし、よろしければ試して頂けるとありがたいです。

実務的には、ビューから該当のtext型のカラムが除去できる
のであればそれに越したことはないのでそれで解決、
という感じでいいと思います。
(もともと業務的に不要だったというのであれば)

ただ、そのビューから除去するというのが、
本来業務的に必要なのに別の方法でtext型を取得したり、
無理矢理ビューを分離したりという形になるのであれば、
それは業務的にはイレギュラーなので、今回のDBFluteの
対応で解決される方が自然です。
(アップグレードができないなら、
AdditionalPrimaryKeyでビューにPK設定)

余談になりますが、Behavior.selectCount(cb) に関しては、
「PKありテーブルのみCLOB・TEXTのUNION問題の回避が可能」
というような扱いにしました。Behavior.selectCount(cb) は、
あくまで「該当テーブルのユニークなカウント」を取得する、
という仕様(のまま)です。
http://dbflute.sandbox.seasar.org/ja/manual/function/ormapper/behavior/select/selectcount.html#clobunion

2010/12/3 kubo <dbf...@gmail.com>:

kubo

unread,
Dec 3, 2010, 5:51:35 AM12/3/10
to dbf...@googlegroups.com
jfluteです。

> 余談になりますが、Behavior.selectCount(cb) に関しては、
> 「PKありテーブルのみCLOB・TEXTのUNION問題の回避が可能」
> というような扱いにしました。Behavior.selectCount(cb) は、
> あくまで「該当テーブルのユニークなカウント」を取得する、
> という仕様(のまま)です。

余談の方ですが、PKが存在するテーブルの場合は、
Union対応の select 句には PK だけを列挙するようにしました。
PKがあるテーブルでは回避も必要ないという感じで。

ドキュメントも更新しています。
http://dbflute.sandbox.seasar.org/ja/manual/function/ormapper/behavior/select/selectcount.html#unioncolumn

DBFlute-0.9.7.7-03-SNAPSHOTが出ています。
もし、まだ試されていないようであればこちらでお願いします。

2010/12/3 kubo <dbf...@gmail.com>:

toshi sugi

unread,
Dec 5, 2010, 10:11:08 PM12/5/10
to DBFluteユーザの集い
jflute様

お返事が遅くなってしまい、申し訳ありません。
バージョンアップさせて頂きこちらで確認を行いました結果、正常に動作しました。
対応ありがとうございました。



On 12月3日, 午後7:51, kubo <dbfl...@gmail.com> wrote:
> jfluteです。
>
> > 余談になりますが、Behavior.selectCount(cb) に関しては、
> > 「PKありテーブルのみCLOB・TEXTのUNION問題の回避が可能」
> > というような扱いにしました。Behavior.selectCount(cb) は、
> > あくまで「該当テーブルのユニークなカウント」を取得する、
> > という仕様(のまま)です。
>
> 余談の方ですが、PKが存在するテーブルの場合は、
> Union対応の select 句には PK だけを列挙するようにしました。
> PKがあるテーブルでは回避も必要ないという感じで。
>
> ドキュメントも更新しています。http://dbflute.sandbox.seasar.org/ja/manual/function/ormapper/behavio...
>
> DBFlute-0.9.7.7-03-SNAPSHOTが出ています。
> もし、まだ試されていないようであればこちらでお願いします。
>
> 2010/12/3 kubo <dbfl...@gmail.com>:
>
> > jfluteです。
>
> > DBFlute-0.9.7.7-02-SNAPSHOT にて反映しました。
> > (モジュール、ランタイム両方)
> > dbflute-sqlserver-example でも反映させてテストしています。
> > もし、よろしければ試して頂けるとありがたいです。
>
> > 実務的には、ビューから該当のtext型のカラムが除去できる
> > のであればそれに越したことはないのでそれで解決、
> > という感じでいいと思います。
> > (もともと業務的に不要だったというのであれば)
>
> > ただ、そのビューから除去するというのが、
> > 本来業務的に必要なのに別の方法でtext型を取得したり、
> > 無理矢理ビューを分離したりという形になるのであれば、
> > それは業務的にはイレギュラーなので、今回のDBFluteの
> > 対応で解決される方が自然です。
> > (アップグレードができないなら、
> > AdditionalPrimaryKeyでビューにPK設定)
>
> > 余談になりますが、Behavior.selectCount(cb) に関しては、
> > 「PKありテーブルのみCLOB・TEXTのUNION問題の回避が可能」
> > というような扱いにしました。Behavior.selectCount(cb) は、
> > あくまで「該当テーブルのユニークなカウント」を取得する、
> > という仕様(のまま)です。
> >http://dbflute.sandbox.seasar.org/ja/manual/function/ormapper/behavio...
>
> > 2010/12/3 kubo <dbfl...@gmail.com>:

kubo

unread,
Dec 5, 2010, 10:28:13 PM12/5/10
to dbf...@googlegroups.com
jfluteです。

確認ありがとうございます。
正式版もできるだけ早めに出したいと思います。
(特に要望があれば遠慮なく言って下さい。
すぐ出して欲しいとか)

2010/12/6 toshi sugi <merup...@gmail.com>:

kubo

unread,
Dec 12, 2010, 8:21:40 PM12/12/10
to dbf...@googlegroups.com
jfluteです。

DBFlute-0.9.7.7-RC1を公開しました。
12月中に正式版を出す予定です。

2010/12/6 kubo <dbf...@gmail.com>:

kubo

unread,
Dec 15, 2010, 1:12:43 AM12/15/10
to dbf...@googlegroups.com
jfluteです。

本件が反映されたバージョン、
DBFlute-0.9.7.7 をリリースしました。
http://d.hatena.ne.jp/jflute/20101215

2010/12/13 kubo <dbf...@gmail.com>:

Reply all
Reply to author
Forward
0 new messages