Oracle de XMLDB #4 Tweet
データベースマガジンでもXQuery1.0は"習うより慣れろ"なんて書いてあったので、使って覚えるのが一番いいだろうなということで前々回に環境を構築したのだが、予想外の展開で、なかなか思うように試す時間がとれない・・・、それでも何とか時間を作らなきゃね。ということでやっとその続き。
バックナンバー:
Oracle de XMLDB #1
Oracle de XMLDB #2
Oracle de XMLDB #3 - Oracle10g XEではどうよ?
最初はFizzBuzzからやってみた。(笑) さずがに、Hello Worldじゃつまらなかったので・・・・。
いつものように、Oracle Database 11g for Linux x86へMacOSXのTerminalからssh接続!
Last login: Sat Oct 20 02:18:51 on console
Welcome to Darwin!
G5Server:˜ discus$ su - oracle
Password:
G5Server:˜ oracle$
G5Server:˜ oracle$ ssh oracle@glasscatfish
oracle@glasscatfish's password:
Last login: Sat Oct 20 02:19:12 2007 from 192.168.1.19
[oracle@glasscatfish ˜]$ sqlplus /nolog
SQL*Plus: Release 11.1.0.6.0 - Production on 月 10月 20 14:13:23 2007
Copyright (c) 1982, 2007, Oracle. All rights reserved.
> conn scott/tiger@lampeye
接続されました。
SCOTT> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production
PL/SQL Release 11.1.0.6.0 - Production
CORE 11.1.0.6.0 Production
TNS for Linux: Version 11.1.0.6.0 - Production
NLSRTL Version 11.1.0.6.0 - Production
SCOTT> set timi on
SCOTT> l
1 xquery
2 for $n in 1 to 100
3 return
4 if ($n mod 15 eq 0) then 'fizzbuzz'
5 else if ($n mod 3 eq 0) then 'fizz'
6 else if ($n mod 5 eq 0) then 'buzz'
7* else $n
SCOTT> /
1
2
fizz
4
buzz
fizz
7
8
fizz
・・・・中略・・・・
fizz
97
98
fizz
buzz
100アイテムが選択されました。
経過: 00:00:00.06
SCOTT>
ついでなので、以前SQLでFizzBuzzしたものと処理時間を比較してみた。
お〜!、SQLでFizzBuzzしたほうが早いな〜!
SCOTT> with
2 t as (
3 select 1 from dual group by cube(1,1,1,1)
4 )
5 select
6 case 0
7 when mod(rownum,15) then 'fizzbuzz'
8 when mod(rownum,3) then 'fizz'
9 when mod(rownum,5) then 'buzz'
10 else to_char(rownum)
11 end as results
12 from
13 t a cross join t b
14 where
15 rownum <= 100;
1
2
fizz
4
buzz
fizz
7
8
・・・・中略・・・・
fizz
97
98
fizz
buzz
100行が選択されました。
経過: 00:00:00.03
SCOTT>
多分、どなたかXQueryでやっているんじゃないかな〜!? ということでググってみたら、ありました、User's Forum For DB2 Japanに。。(^^;;;
いや〜〜〜、目から鱗ですね。User's Forum For DB2 Japanのスレッドにある下記コードは、面白い。(私のコードは読みやすいかもしれないが、ストレート過ぎるかもね。ちょいと捻ったほうが、XQueryのトリッキーな動きも見えてくるというもの。)
以下のコードは、XPath2.0/XQuery1.0では、xs:booleanじゃなくても真理値として扱われる値やシーケンスにフィルタ式を用いているなどなど参考になります。m(_ _)m
(ただ、xs:booleanじゃなくても真理値として扱われるという性質を多用しるぎると難読化傾向はあるかもしれないですね。)
SCOTT> l
1 xquery
2 for $n in 1 to 100
3 return
4 fn:concat(
5 $n[($n mod 3 and $n mod 5)],
6 'fizz'[fn:not($n mod 3)],
7 'buzz'[fn:not($n mod 5)]
8* )
SCOTT> /
1
2
fizz
4
buzz
fizz
7
8
・・・・中略・・・・
97
98
fizz
buzz
100アイテムが選択されました。
経過: 00:00:00.06
SCOTT>
XQueryの条件式を少々書き換えてみた。私が最初に書いたXQueryより条件式の部分が読みにくくなりますよね、やはり。(実行速度に影響がなければ、読みやすい方がいいな。。)
SCOTT> l
1 xquery
2 for $n in 1 to 100
3 return
4 if (fn:not($n mod 15)) then 'fizzbuzz'
5 else if (fn:not($n mod 3)) then 'fizz'
6 else if (fn:not($n mod 5)) then 'buzz'
7* else $n
SCOTT> /
1
2
fizz
4
buzz
fizz
7
8
・・・・中略・・・・
97
98
fizz
buzz
100アイテムが選択されました。
経過: 00:00:00.06
SCOTT>
やはりxs:booleanじゃなくても真理値として扱われるという性質は、間違いやすいところなのでもうちょっと突っ込んで理解しておく必要があるなぁ。いい加減に覚えているとハマりそうな予感。
2007/10/23 追記
Oracle10g R2でもできますよ。
| 固定リンク | 0
コメント