2016年3月27日 (日)

OracleのB*Tree索引にはNULLが含まれる場合があるんです! - その性質を使ってチューニングすることもあるよ:) その3


前回までのMac De Oracle

OracleのB*Tree索引にはNULLが含まれる場合があるんです! - その性質を使ってチューニングすることもあるよ:)
OracleのB*Tree索引にはNULLが含まれる場合があるんです! - その性質を使ってチューニングすることもあるよ:) その2

ということで、続きで〜〜すっ。

こんな表定義で

orcl@SCOTT> desc tab01
Name Null? Type
--------- -------- --------
FOO NUMBER
BAR NUMBER
HOGE NOT NULL CHAR(2)
ID NOT NULL NUMBER

こんな索引があって

****** Index column info : tab01 ******

INDEX_NAME COLUMN_NAME DESC
------------------------------ ------------------------------ ----
IX1_TAB01 FOO ASC

IX2_TAB01 BAR ASC
FOO ASC

IX3_TAB01 ID ASC
FOO ASC

IX4_TAB01 ID ASC
BAR ASC
FOO ASC

PK_TAB01 ID ASC


こんなデータで

orcl@SCOTT> set null [NULL]
orcl@SCOTT> select * from tab01

FOO BAR HO ID
---------- ---------- -- ----------
[NULL] [NULL] ** 1
1 [NULL] ** 2
[NULL] 1 ** 3
1 1 ** 4


2列の複合索引、どちらの列もNULLだと、やはり、NULLは索引に含まれないので IS NULL検索だと索引は利用されないですよねぇ〜。このような状態ではヒントで索引利用を強制利用させようとしても無理です。

orcl@SCOTT> r
1 select
2 /*+
3 gather_plan_statistics
4 index(tab01 ix2_tab01)
5 no_index(tab01 ix4_tab01)
6 no_index(tab01 ix3_tab01)
7 */
8 *
9 from
10 tab01
11 where
12 foo is null
13* and bar is null
     
FOO BAR HO ID
---------- ---------- -- ----------
[NULL] [NULL] ** 1

・・・略・・・
-------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 8 |
|* 1 | TABLE ACCESS FULL| TAB01 | 1 | 1 | 1 |00:00:00.01 | 8 |
-------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter(("FOO" IS NULL AND "BAR" IS NULL))

でも、NOT NUL制約の列が1列でも含まれている索引であればNULLは索引に含まれます。(前回までの復習も兼ねた確認)
第1列がWHERE句で記述されていないので索引スキップスキャンになっていますが.....IS NULL検索を索引アクセスだけで行っているのがよく分かる例の一つです:)

orcl@SCOTT> r
1 select
2 /*+
3 gather_plan_statistics
4 */
5 *
6 from
7 tab01
8 where
9 foo is null
10* and bar is null

FOO BAR HO ID
---------- ---------- -- ----------
[NULL] [NULL] ** 1

・・・略・・・
--------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
--------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 3 | 1 |
| 1 | TABLE ACCESS BY INDEX ROWID BATCHED| TAB01 | 1 | 1 | 1 |00:00:00.01 | 3 | 1 |
|* 2 | INDEX SKIP SCAN | IX4_TAB01 | 1 | 1 | 1 |00:00:00.01 | 2 | 1 |
--------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - access("BAR" IS NULL AND "FOO" IS NULL)
filter(("FOO" IS NULL AND "BAR" IS NULL))


最後にもう少しわかりやすい例を。

SQL文を少々書き換えてIndex Only Scanになるようにしました。索引にNULLが含まれていないと索引だけのアクセスで済むわけがないわけで、これ以上わかりやすい例はないと思います:)

まず、索引が利用できない例から。
FOO列とBAR列だけの複合索引をヒントで強制利用させようとしていますが、この索引は2列ともnullableなので2列をIS NULL検索しても索引が利用されません!
全ての列がNULLである場合、キーエントリーは索引に作成されない。単一列でも複合索引でも同じであることが確認できます。

orcl@SCOTT> r
1 select
2 /*+
3 gather_plan_statistics
4 index(tab01 ix2_tab01)
5 no_index(tab01 ix4_tab01)
6 no_index(tab01 ix3_tab01)
7 */
8 *
9 from
10 tab01
11 where
12 foo is null
13* and bar is null

FOO BAR HO ID
---------- ---------- -- ----------
[NULL] [NULL] ** 1

・・・略・・・
-------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 8 |
|* 1 | TABLE ACCESS FULL| TAB01 | 1 | 1 | 1 |00:00:00.01 | 8 |
-------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter(("FOO" IS NULL AND "BAR" IS NULL))

おっと、
大切なのを忘れてました。

FOO列(nullable(、BAR列(nullable)の複合索引を IS NOT NULL AND IS NULLで検索した場合はどうなるか?
答えは以下の通り。IS NULL と IS NOT NULLの組み合わせでも、索引が利用されます。:)

BAR IS NULLで範囲検索しFOO IS NOT NULLでフィルタリングしています。 NULLが含まれていないと不可能な索引レンジスキャンと索引読み時のフィルタリング!

orcl@SCOTT> r
1 select
2 /*+
3 gather_plan_statistics
4 no_index(tab01 ix3_tab01)
5 no_index(tab01 ix4_tab01)
6 */
7 foo
8 , bar
9 from
10 tab01
11 where
12 foo is not null
13* and bar is null

FOO BAR
---------- ----------
1 [NULL]

・・・略・・・
-------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
-------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.02 | 1 | 1 |
|* 1 | INDEX RANGE SCAN| IX2_TAB01 | 1 | 1 | 1 |00:00:00.02 | 1 | 1 |
-------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------

1 - access("BAR" IS NULL)
filter("FOO" IS NOT NULL)

その逆も!

orcl@SCOTT> r
1 select
2 /*+
3 gather_plan_statistics
4 no_index(tab01 ix3_tab01)
5 no_index(tab01 ix4_tab01)
6 */
7 foo
8 , bar
9 from
10 tab01
11 where
12 foo is null
13* and bar is not null

FOO BAR
---------- ----------
[NULL] 1

・・・略・・・
----------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 2 |
|* 1 | INDEX SKIP SCAN | IX2_TAB01 | 1 | 1 | 1 |00:00:00.01 | 2 |
----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - access("FOO" IS NULL)
filter(("FOO" IS NULL AND "BAR" IS NOT NULL))


もういっちょ!
2列とものnullableな索引だとindex fast full scanにはできないけど、index full scanにはできるんですよ〜。

orcl@SCOTT7gt; r
1 select
2 /*+
3 gather_plan_statistics
4 no_index(tab01 ix3_tab01)
5 no_index(tab01 ix4_tab01)
6 */
7 foo
8 , bar
9 from
10 tab01
11 where
12 foo is not null
13* and bar is not null

FOO BAR
---------- ----------
1 1

・・・略・・・
----------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 2 |
|* 1 | INDEX FULL SCAN | IX2_TAB01 | 1 | 1 | 1 |00:00:00.01 | 2 |
----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter(("FOO" IS NOT NULL AND "BAR" IS NOT NULL))

Note
-----
- statistics feedback used for this statement

後に、NOT NULL列が含まれる索引なら index fast full scanでもできるはず!
独り言;index only scan+index fast full scanなんてのもセグメントサイズが小さければ物理読み込み量削減には効果があるんですよねぇ〜 ;-)

orcl@SCOTT> r
1 select
2 /*+
3 gather_plan_statistics
4 no_index(tab01 ix3_tab01)
5 index_ffs(tab01 ix4_tab01)
6 no_index(tab01 ix2_tab01)
7 */
8 foo
9 , bar
10 from
11 tab01
12 where
13 foo is not null
14* and bar is not null

FOO BAR
---------- ----------
1 1

・・・略・・・
-----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
-----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.03 | 4 | 1 |
|* 1 | INDEX FAST FULL SCAN| IX4_TAB01 | 1 | 1 | 1 |00:00:00.03 | 4 | 1 |
-----------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - filter(("FOO" IS NOT NULL AND "BAR" IS NOT NULL))


オラクルの索引にNULLは絶対含まれない、というのは都市伝説! 
IS NOT NULLは索引使えないとかIS NULLは索引使えないというというのも違うんですよね。 

OracleのB*Tree索引では、索引に含まれる全列がNULLの場合以外はNULLが含まれてまっす! というのが正しいですよね!?

この手の問題でピンチになったら、思い出してみてください ;)
USE THE INDEX ONLY SCAN, LUKE! w

| | コメント (0) | トラックバック (0)

2013年4月 8日 (月)

db file scattered read と db file parallel read と db file sequential read (その4)

db file scattered read と db file parallel read と db file sequential read の続きです。

再びリクエストにお答えしてw、SQLとレースを有効した状態でstraceして該当待機イベントでどのようなsystem callになっているのか確認してみたよ > @yoheia :)


db file sequential read

WAIT #4: nam='db file sequential read' ela= 53584 file#=7 block#=375476 blocks=1 obj#=82773 tim=1365258291285100

....
pread64(17, "\6\242\0\0\372\267\5\0\\]\216\0\0\0\1\6\226y\0\0\1\0\0\0UC\1\0009]\216\0"..., 8192, 3070181376) = 8192

db file scattered read

WAIT #4: nam='db file scattered read' ela= 14462 file#=7 block#=374752 blocks=26 obj#=82773 tim=1365258291450333

....
pread64(17, "\6\242\0\0\340\267\5\0005]\216\0\0\0\1\6}\372\0\0\1\0\0\0UC\1\0002]\216\0"..., 212992, 3069968384) = 212992

db file parallel read

WAIT #4: nam='db file parallel read' ela= 25040 files=1 blocks=11 requests=11 obj#=82773 tim=1365258291641614

....
io_submit(1261568, 11, {{0x7981c8, 0, 0, 0, 17}, {0x79834c, 0, 0, 0, 17}, {0x7984d0, 0, 0, 0, 17}, {0x798654, 0, 0, 0, 17}, {0x7987d8, 0, 0, 0, 17}, {0x79895c, 0, 0, 0, 17}, {0x798ae0, 0, 0, 0, 17}, {0x798c64, 0, 0, 0, 17}, {0x798de8, 0, 0, 0, 17}, {0x798f6c, 0, 0, 0, 17}, {0x7990f0, 0, 0, 0, 17}}) = 11
io_getevents(1261568, 11, 128, {{0x79834c, 0x79834c, 8192, 0}, {0x7984d0, 0x7984d0, 8192, 0}, {0x7981c8, 0x7981c8, 8192, 0}, {0x798654, 0x798654, 8192, 0}, {0x7987d8, 0x7987d8, 8192, 0}, {0x798ae0, 0x798ae0, 8192, 0}, {0x798c64, 0x798c64, 8192, 0}, {0x798de8, 0x798de8, 8192, 0}, {0x7990f0, 0x7990f0, 8192, 0}, {0x798f6c, 0x798f6c, 8192, 0}, {0x79895c, 0x79895c, 8192, 0}}, {600, 0}) = 11

このdb file parallel readも狙って出せるくらいだから、たまたまそういう状況では発生しちゃうわけですよ。

以下のSQLトレースは、全てHIGH_CLUSTERING_FACTOR(表)に対する待機イベントですが、何が起きているか想像するとワクワクしてきませんか? (変態だな)

WAIT #4: nam='db file parallel read' ela= 10307 files=1 blocks=14 requests=14 obj#=82773 tim=1364725159669764 
WAIT #4: nam='db file scattered read' ela= 1931 file#=7 block#=374755 blocks=29 obj#=82773 tim=1364725159671819
WAIT #4: nam='db file parallel read' ela= 5874 files=1 blocks=14 requests=14 obj#=82773 tim=1364725159733551 
WAIT #4: nam='db file sequential read' ela= 337 file#=7 block#=374065 blocks=1 obj#=82773 tim=1364725159733959 

ということで、いろいろと、力尽きたので今日はここまで。

次回へつづく。


バックナンバー

db file scattered read と db file parallel read と db file sequential read (その1)
db file scattered read と db file parallel read と db file sequential read (その2)
db file scattered read と db file parallel read と db file sequential read (その3)

| | コメント (0) | トラックバック (0)

2012年1月30日 (月)

AWRレポート、AWR SQLレポート一括取得スクリプトを作ったよ。

Statspackレポートもそうなのですが、AWRレポート/AWR SQLレポートも個別に取得していると凄ーく辛いんですよね。一日分出力するとか、AWRレポートで処理時間の長いSQL文のAWR SQLレポートを個別に取得しようとなると...

ただでさえ忙しいのに、AWRレポート取得するのに時間掛けたくないですよね。

ということで、やっつけで作ったのですが、そのまま載せるのもあれなんで、やっつけで作った感じを多少減らしてgithubに公開しました。;)

https://github.com/discus/Oracle-AWR-batch-generation-script/blob/master/awrreport_batch.sql


もっといい感じに改造してくれるといいな〜とかとか... :)

Oracle11g R1/R2 Enterprise Edition、HTML形式で出力します。(RAC環境では試してないので多分だめかと。)。
AWRを利用するには追加ライセンスが必要なのでご注意を


使い方は・・

SQL*plusを起動し、select any dictionaryシステム権限、dbms_repositoryパッケージの実行権限が付与されたユーザで接続して実行するだけ。
SYSTEMユーザでやる事が多いけど、所変わればなんとやらなので・・・そこんとこよろしく。(w


一括取得なので実行当日を含めてn日分のAWRレポートを取得し、同時に処理時間の長いTop20のAWR SQLレポートも取得します。
レポートは各スナップショット間(今のところ固定)で取得します。

指定するパラメータは、以下の3つ。

Enter snap_id for starting AWR report generation. [NULL] : 
AWRレポートを取得する最初のSNAP_IDを指定します。 NULLがデフォルトでほとんどの場合デフォルトのままで事足りると思います。


Enter number of days for reporting period. [1] : 

一括取得する日数を指定します。当日を含みます。
当日分のAWRレポートを出力するのであれば、デフォルト値の1のままでOKです。


Enter suffix for AWR reports filename. [NULL] : test

保存するAWRレポートのファイル名に付加するsuffixを指定します。
試験名とか設定するといいですよね。

"test"と指定した場合

awrrpt_nnnn_nnnn_test.htmlや
awrsqrpt_nnnn_nnnn_test_sqlid.html

の形式で保存します。(nnnnはSNAP_ID)


実行例1)当日分の全レポートを取得する例

SYSTEM> 
SYSTEM> !ls -l awr*.sql
-rw-r--r-- 1 oracle oinstall 6065 1月 29 18:23 awrreport_batch.sql

SYSTEM> @awrreport_batch
--
-- Oracle AWR and AWR SQL report batch generation script
--
-- ***** This script always generate html format AWR reports. *****
--
Enter snap_id for starting AWR report generation. [NULL] :
Enter number of days for reporting period. [1] :
Enter suffix for AWR reports filename. [NULL] : test
--
--
--
clear break compute;
repfooter off;
ttitle off;
btitle off;

・・・中略・・・

<p />
<br /><a class="awr" href="#top">Back to Top</a><p />
</body></html>

SYSTEM>


実行例2)当日分かつsnap_id=291以降で一括取得。(事前にsnap_idを調べておいてね)

SYSTEM> 
SYSTEM> @awrreport_batch
--
-- Oracle AWR and AWR SQL report batch generation script
--
-- ***** This script always generate html format AWR reports. *****
--
Enter snap_id for starting AWR report generation. [NULL] : 291
Enter number of days for reporting period. [1] :
Enter suffix for AWR reports filename. [NULL] : test
--
--
--
clear break compute;
repfooter off;
ttitle off;
btitle off;

・・・中略・・・

<p />
<br /><a class="awr" href="#top">Back to Top</a><p />
</body></html>

SYSTEM>
SYSTEM>
SYSTEM> !ls -l *.html
-rw-r--r-- 1 oracle oinstall 379083 1月 29 22:23 awrrpt_291_292_test.html
-rw-r--r-- 1 oracle oinstall 11899 1月 29 22:23 awrsqrpt_291_292_test_0c83z9rqx45hu.html
-rw-r--r-- 1 oracle oinstall 11899 1月 29 22:23 awrsqrpt_291_292_test_0h3mfbzk6uyw0.html
-rw-r--r-- 1 oracle oinstall 11897 1月 29 22:23 awrsqrpt_291_292_test_2p7t0mw7zvu5z.html

・・・中略・・・

-rw-r--r-- 1 oracle oinstall 11899 1月 29 22:23 awrsqrpt_291_292_test_bhtycgwkxhfj9.html
-rw-r--r-- 1 oracle oinstall 11900 1月 29 22:23 awrsqrpt_291_292_test_bpaggvtfkar9k.html
-rw-r--r-- 1 oracle oinstall 11899 1月 29 22:23 awrsqrpt_291_292_test_c50hdbyuwhfn6.html
-rw-r--r-- 1 oracle oinstall 11892 1月 29 22:23 awrsqrpt_291_292_test_g3f3cw3zy5aat.html

SYSTEM>

なお、Oracleインスタンスが再起動された期間でawrrpt.sqlなどを実行すると、レポートが作成できずエラーでSQL*Plusも終了してしまいますが、本スクリプトでは該当部分のレポートはスキップするようにしてあります。:)

Instance     DB Name      Snap Id   Snap Started       Level
------------ ------------ --------- ------------------ -----
lampeye LAMPEYE 274 29 1月 2012 09:33 1
275 29 1月 2012 10:00 1
276 29 1月 2012 10:30 1
277 29 1月 2012 11:00 1
278 29 1月 2012 11:30 1
279 29 1月 2012 12:00 1
280 29 1月 2012 12:30 1
281 29 1月 2012 13:00 1
282 29 1月 2012 13:30 1
283 29 1月 2012 14:00 1
284 29 1月 2012 14:30 1
285 29 1月 2012 15:00 1
286 29 1月 2012 15:30 1
287 29 1月 2012 16:00 1
288 29 1月 2012 16:30 1
289 29 1月 2012 17:00 1
290 29 1月 2012 17:30 1

291 29 1月 2012 18:31 1 ←再起動されてる
292 29 1月 2012 18:34 1

293 29 1月 2012 22:26 1 ←再起動されてる


Enjoy!

| | コメント (2) | トラックバック (0)

2010年6月 2日 (水)

Dashboard de Aquarium v1.5 released!

Dashboard de Aquarium v1.5をリリースしました。いくつかの問題点の修正と、アフリカン・ランプアイを追加しました。
(Dashboard de Aquarium v1.5 released.
What's new in this version : Fixed some bugs and added African Lampeye.)

Picture_2_2

Download Dashboard De Aquarium v1.5 Now!

Download! v1.5 dashboard_de_aquarium.zip (996KB)

Dashboard de Aquarium v1.6 released. (v1.6をリリースしました 2012/01/01)

日本語(Japanese):
"Mac OS X 10.4 Tiger以降が必要です。ダウンロードにSafariを使用する場合は、はじめにダウンロードのリンクをクリックしてください。次にダウンロードの完了後、ウィジェットを表示し、プラスボタンをクリックしてウィジェットバーを表示させ、ダウンロードしたウィジェットを追加してください。Safari以外のブラウザを使用する場合は、はじめにダウンロードのリンクをクリックしてください。次にダウンロードの完了後、解凍したウィジェットを /ライブラリ/Widgets/ フォルダに配置してください。ウィジェットを表示し、プラスボタンをクリックしてウィジェットバーを表示させ、ダウンロードしたウィジェットを追加してください。"

English:
"Mac OS X 10.4 Tiger or later is required. If you’re using Safari, click the download link. When the widget download is complete, show Dashboard, click the Plus sign to display the Widget Bar and click the widget’s icon in the Widget Bar to open it. If you’re using a browser other than Safari, click the download link. When the widget download is complete, unarchive it and place it in /Library/Widgets/ in your home folder. show Dashboard, click the Plus sign to display the Widget Bar and click the widget’s icon in the Widget Bar to open it."


動作確認した機種とMacOSXのバージョンは以下の通り。
(H/W models and the version of MacOSX that I checked the operation as follows.)

System Requirements : MacOSX Tiger 10.4 or later -- Freeware.

PowerBook G4 1Ghz - MacOSX 10.5.8 (Leopard)
PowerMac G5 Dual 2.7Ghz - MacOSX 10.4.11 (Tiger)
MacBook Pro 2.2Ghz Core 2 Duo - MacOSX 10.6 (Snow Leopard)

Note: 国際化対応しています。言語環境が日本語であればメニューやボタンのテキストは日本語で表示されます。
Screen_shot_20100601_at_221756 Screen_shot_20100601_at_221810
Screen_shot_20100601_at_221821 Screen_shot_20100601_at_221832
Screen_shot_20100601_at_221840 Screen_shot_20100601_at_221915
Screen_shot_20100601_at_221936 Screen_shot_20100601_at_221946_2
Screen_shot_20100601_at_221750
Screen_shot_20100601_at_221741

| | コメント (0) | トラックバック (0)

2009年7月11日 (土)

Dashboard de Aquarium v1.4 released!

Dashboard de Aquarium v1.6 released. :) (v1.6リリースしました 2012/01/01)

Dashboard de Aquarium v1.4をリリースしました。今回のリリースではwidgetサイズを縮小したついでにRed Sailfin mollyを追加しました。
(Dashboard de Aquarium v1.4 released.
What's new in this version : Reduced widget size a little and added Red Sailfin Molley.)

Download Dashboard De Aquarium v1.4 Now!
Download! v1.4 dashboard_de_aquarium.zip (904KB)

Dashboard de Aquarium v1.6 released.
(v1.6リリースしました 2012/01/01)

日本語(Japanese):
"Mac OS X 10.4 Tiger以降が必要です。ダウンロードにSafariを使用する場合は、はじめにダウンロードのリンクをクリックしてください。次にダウンロードの完了後、ウィジェットを表示し、プラスボタンをクリックしてウィジェットバーを表示させ、ダウンロードしたウィジェットを追加してください。Safari以外のブラウザを使用する場合は、はじめにダウンロードのリンクをクリックしてください。次にダウンロードの完了後、解凍したウィジェットを /ライブラリ/Widgets/ フォルダに配置してください。ウィジェットを表示し、プラスボタンをクリックしてウィジェットバーを表示させ、ダウンロードしたウィジェットを追加してください。"

English:
"Mac OS X 10.4 Tiger or later is required. If you’re using Safari, click the download link. When the widget download is complete, show Dashboard, click the Plus sign to display the Widget Bar and click the widget’s icon in the Widget Bar to open it. If you’re using a browser other than Safari, click the download link. When the widget download is complete, unarchive it and place it in /Library/Widgets/ in your home folder. show Dashboard, click the Plus sign to display the Widget Bar and click the widget’s icon in the Widget Bar to open it."


動作確認した機種とMacOSXのバージョンは以下の通り。
(H/W models and the version of MacOSX that I checked the operation as follows.)

System Requirements : MacOSX Tiger 10.4 or later -- Freeware.

PowerBook G4 1Ghz - MacOSX 10.4.11 (Tiger)
PowerMac G5 Dual 2.7Ghz - MacOSX 10.4.11 (Tiger)
MacBook Pro 2.2Ghz Core 2 Duo - MacOSX 10.5.6 (Leopard) / MacOSX 10.6 (Snow Leopard)

Mixed_jaNeontetra_ja
Discus_jaWild_king_solid_blue_f1_ja
Licksons_red_spotted_jaHides_wild_blue_wild_brown_ja
9
10

Note: 国際化対応しています。言語環境が英語であれば以下のように表示されます。
(Internationalized. When language setting is in English, it's displayed as follows.)

MixedNeontetra
DiscusWild_king_solid_blue_f1
Licksons_red_spottedHides_wild_blue_wild_brown
Picture_1
Picture_2

| | コメント (0) | トラックバック (0)

2009年3月 8日 (日)

Dashboard de Aquarium v1.3 released!

Dashboard de Aquarium v1.6 released.
(v1.6をリリースしましたよ〜 2012/01/01)


Dashboard de Aquarium v1.3をリリースしました。今回のリリースではFallin Hobby (formaly discus family)のhideさんのご協力により3種のディスカスを追加しました。hideさんありがとうございました。

尚、現時点では旧リリースのv1.2もダウンロード可能ですが、Apple US/Japanでv1.3公開後にはv1.2のダウンロードを停止予定です。


動作確認した機種とMacOSXのバージョンは以下の通り。
(H/W models and the version of MacOSX that I checked the operation as follows.)

System Requirements : MacOSX Tiger 10.4 or later -- Freeware.

PowerBook G4 1Ghz - MacOSX 10.4.11 (Tiger)
PowerMac G5 Dual 2.7Ghz - MacOSX 10.4.11 (Tiger)
MacBook Pro 2.2Ghz Core 2 Duo - MacOSX 10.5.6 (Leopard)

Mixed_jaNeontetra_ja
Discus_jaWild_king_solid_blue_f1_ja
Licksons_red_spotted_jaHides_wild_blue_wild_brown_ja
Back_with_pref_2

★★2009/7/11 Dashboard de Aquarium v1.4 をリリースしました。詳細はこのリンクをクリック!★★

★★ 11-Jul-2009 Dashboard de Aquarium v1.4 released
See download page. ★★

日本語(Japanese):
"Mac OS X 10.4 Tiger以降が必要です。ダウンロードにSafariを使用する場合は、はじめにダウンロードのリンクをクリックしてください。次にダウンロードの完了後、ウィジェットを表示し、プラスボタンをクリックしてウィジェットバーを表示させ、ダウンロードしたウィジェットを追加してください。Safari以外のブラウザを使用する場合は、はじめにダウンロードのリンクをクリックしてください。次にダウンロードの完了後、解凍したウィジェットを /ライブラリ/Widgets/ フォルダに配置してください。ウィジェットを表示し、プラスボタンをクリックしてウィジェットバーを表示させ、ダウンロードしたウィジェットを追加してください。"

English:
"Mac OS X 10.4 Tiger or later is required. If you’re using Safari, click the download link. When the widget download is complete, show Dashboard, click the Plus sign to display the Widget Bar and click the widget’s icon in the Widget Bar to open it. If you’re using a browser other than Safari, click the download link. When the widget download is complete, unarchive it and place it in /Library/Widgets/ in your home folder. show Dashboard, click the Plus sign to display the Widget Bar and click the widget’s icon in the Widget Bar to open it."


Note: 国際化対応しています。言語環境が英語であれば以下のように表示されます。
(Internationalized. When language setting is in English, it's displayed as follows.)

MixedNeontetra
DiscusWild_king_solid_blue_f1
Licksons_red_spottedHides_wild_blue_wild_brown
Back_with_pref_3

| | コメント (0) | トラックバック (0)

2009年1月18日 (日)

Dashboard de Aquarium v1.2 released!!

前回の予告したようにDashboard de Aquarium v1.2をリリースしました。今回のリリースで魚種(discus/neon tetra/mix:default)を選択することができるようになりました。
(Dashboard de Aquarium v1.2 new feature : Added preference pane and you can choose fish species(discus, neon tetra or mix:default).


(2009/1/18現在:
しばらくの間はv1.1もダウンロードできるようにしておきますが、Appleからのリンクが更新された時点でv1.1はダウンロードできなくする予定ですのでご了承ください。)

20-Jan-2009:
Apple(US)からのリンクは変更されましたがApple(Japan)からのリンクはまだ変更されていないようなのでもうしばらくv1.1のダウンロードは可能なままにしておきます。

6-Feb-2009
Apple(Japan)でも公開されたので旧リリースのダウンロードは停止します。

11-Mar-2009
Dashboard de Aquarium v1.3リリースに伴い、Apple US/Japanで公開後にv1.2のダウンロードは停止する予定です。


動作確認した機種とMacOSXのバージョンは以下の通り。
(H/W models and the version of MacOSX that I checked the operation as follows.)

System Requirements : MacOSX Tiger 10.4 or later -- Freeware.

PowerBook G4 1Ghz - MacOSX 10.4.11 (Tiger)
PowerMac G5 Dual 2.7Ghz - MacOSX 10.4.11 (Tiger)
MacBook Pro 2.2Ghz Core 2 Duo - MacOSX 10.5.6 (Leopard)

v1.2(default)
v1.2(Discus) v1.2(neon tetra)
v1.2 back
v1.2 preference pane v1.2 popupmenu

Download Dashboard De Aquarium v1.2 Now!
Download! v1.2 dashboard_de_aquarium.zip (708KB)

日本語(Japanese):
"Mac OS X 10.4 Tiger以降が必要です。ダウンロードにSafariを使用する場合は、はじめにダウンロードのリンクをクリックしてください。次にダウンロードの完了後、ウィジェットを表示し、プラスボタンをクリックしてウィジェットバーを表示させ、ダウンロードしたウィジェットを追加してください。Safari以外のブラウザを使用する場合は、はじめにダウンロードのリンクをクリックしてください。次にダウンロードの完了後、解凍したウィジェットを /ライブラリ/Widgets/ フォルダに配置してください。ウィジェットを表示し、プラスボタンをクリックしてウィジェットバーを表示させ、ダウンロードしたウィジェットを追加してください。"

English:
"Mac OS X 10.4 Tiger or later is required. If you’re using Safari, click the download link. When the widget download is complete, show Dashboard, click the Plus sign to display the Widget Bar and click the widget’s icon in the Widget Bar to open it. If you’re using a browser other than Safari, click the download link. When the widget download is complete, unarchive it and place it in /Library/Widgets/ in your home folder. show Dashboard, click the Plus sign to display the Widget Bar and click the widget’s icon in the Widget Bar to open it."


Note: 国際化対応しています。言語環境が英語であれば以下のように表示されます。
(Internationalized. When language setting is in English, it's displayed as follows.)

v1.2 default
v1.2(discus) v1.2(neon tetra)
v1.2 back
v1.2 preference pane Picture_4

| | コメント (0) | トラックバック (0)

2008年3月 3日 (月)

Mercedes-Benz Mixed Tape TV

Mercedes-Benz Mixted Tapeのサイトがバージョンアップして、かな〜〜〜りイケてるサイトに生まれ変わった!
iTunesのカバーフローを意識したインタ−フェースや、メルセデスに関する情報も上手くリンクされている。



ダウンロードした曲は、iTunesやiPodへ入れちゃいます。ジャンルは幅広いのですが、いい楽曲が非常に多いので私のお気に入りです。

| | コメント (0) | トラックバック (0)

2007年11月 1日 (木)

Dashboard De Aquarium v1.1 - Released!

6-Feb-2009:
Dashboard de Aquarium v1.2 released!!!!, Download NOW!!
(Apple社(US及び日本)でv1.2が公開されるたのでv1.1のダウンロードは停止しました。


translate from japanese to english : Powered by Google translate

前回の予告したようにMacOSX 10.5 LeopardでDashboard De Aquarium v1.0を実行した場合に発生する問題を解決したDashboard De Aquarium v1.1リリースしました。

(これに伴いv1.0のダウンロードはできなくなります。)


動作確認した機種とMacOSXのバージョンは以下の通り。

System Requirements : MacOSX Tiger 10.4 or later -- Freeware.

PowerBook G4 1Ghz - MacOSX 10.4.10 (Tiger)
PowerMac G5 Dual 2.7Ghz - MacOSX 10.4.10 (Tiger)
MacBook Pro 2.2Ghz Core 2 Duo - MacOSX 10.5 (Leopard)

V1_1_on_leopard

V1_1_on_leopard_1 V1_1_on_leopard_2

Download Now!
Go to v1.2 download page!

"Mac OS X 10.4 Tiger以降が必要です。ダウンロードにSafariを使用する場合は、はじめにダウンロードのリンクをクリックしてください。次にダウンロードの完了後、ウィジェットを表示し、プラスボタンをクリックしてウィジェットバーを表示させ、ダウンロードしたウィジェットを追加してください。Safari以外のブラウザを使用する場合は、はじめにダウンロードのリンクをクリックしてください。次にダウンロードの完了後、解凍したウィジェットを /ライブラリ/Widgets/ フォルダに配置してください。ウィジェットを表示し、プラスボタンをクリックしてウィジェットバーを表示させ、ダウンロードしたウィジェットを追加してください。"


Note: 国際化対応しています。言語環境が英語であれば以下のように表示されます。
V1_1_on_leopard_en_us_1 V1_1_on_leopard_en_us_2

| | コメント (3) | トラックバック (0)

2007年5月11日 (金)

Dashboard De Aquarium (v1.0)

translate from japanese to english : Powered by Google translate

ここのところOracleネタが少ないですが、今日も Dashcodeネタということで。。。

Dashboard De Aquarium v1.0をリリースしました。

System Requirements : MacOSX Tiger 10.4 or later -- Freeware.
今のところ、魚種や個体数などの変更はできません。

水槽を泳ぐdiscusは、サイドバーに配置してある画像から切り抜いたdiscusです。このdiscusは、14年ほど前に約1万円で購入した個体でした。初めてdiscusを飼う上、高価な買い物には勇気がいりました。 もし、ネオンテトラだったとしたら、何匹買えたことでしょう!・・・

Dashboard_de_aquarium_front2 Dashboard_de_aquarium_back2

Dashboard_de_aquarium_icon

Dashboard_de_aquarium_front Dashboard_de_aquarium_back


2007/11/1 - updated
Leopard上で発生する問題を解決した v1.1をリリースしましたので
 ==>こちらのページからダウンロードしてください。


"Mac OS X 10.4 Tigerが必要です。ダウンロードにSafariを使用する場合は、はじめにダウンロードのリンクをクリックしてください。次にダウンロードの完了後、ウィジェットを表示し、プラスボタンをクリックしてウィジェットバーを表示させ、ダウンロードしたウィジェットを追加してください。Safari以外のブラウザを使用する場合は、はじめにダウンロードのリンクをクリックしてください。次にダウンロードの完了後、解凍したウィジェットを /ライブラリ/Widgets/ フォルダに配置してください。ウィジェットを表示し、プラスボタンをクリックしてウィジェットバーを表示させ、ダウンロードしたウィジェットを追加してください。"


Note: 国際化対応しています。言語環境が英語であれば以下のように表示されます。
Dashboard_de_aquarium_en_f Dashboard_de_aquariuim_en_b




実は、2000年頃、このWidgetの元となるWebページを公開していたのですが、Netscape 4.xのみ(layerを使っていたことも理由ですが。)に対応していました。
国外の方も含めて、「IEには対応しないのか?」 とメールを頂いたこともありましたがやる気が起きず、Mozillaや Safariの登場とともにお蔵入させていましたが、今回、Widget版として復活させました。


以下のスクリーンショットは、Classic環境のNetscape 4.0で、当時(2000年頃)のjavascriptを実行したものです。

Old_netscape4x_version

| | コメント (2) | トラックバック (0)

2007年5月 6日 (日)

iMovie キッズワークショップ

GWに開催されたApple StoreのiMovieキッズワークショップに姪を連れて参加してきた。
(Oracleのネタは全くありませんのであしからず。。)

会場となったApple Ginza Storeの1階と4階を、子供自身が決めたテーマに従い10シーン×10秒程度で撮影し、BGMは付けないという事だった為、持参したビデオテープと私がGarageBand3で急遽作成したBGMを使う事は無かった。。。。。。

少々、残念だったが姪は、大満足!!!


Cimg3763

小さい子供でもMacBookiLife '06があれば、映画作れちゃうんですよ。簡単に!!!


BGMに利用しようと、急遽、GarageBand3で作成したサウンとドラック。(ご自由にご利用ください。)
なんとなく懐かしく感じる、Techno Pop風な曲にしてあります。


Aificonダウンロード MacDeOracleSoundTrack3.aif (フォーマット :aif ,6904.9K)


他にも、姪は良い経験をしたようだ。

●地下鉄で銀座まで来た事も初めて!
●自分一人で、自動改札に切符を通して出入りしたのも初めて!
●20時に帰宅したのだが、そんな時間まで外出しているのも初めて!
 (いつもは、18時に夕食、21時には就寝。。)
●当然だが、MacのiMovieで映画を作るなんて初めて!
●自分でデジタルビデオを操作して撮影するのも初めて!

初めてがいっぱいだ〜〜〜!。 と、うれしそうに話していた!

さらに、キッズワークショップ限定 Tシャツも頂き、うれしそう!! (^^;;;;

Cimg3764_1




余談だが、
姪に、大きくなったらこんな迷路みたいな地下鉄乗り継いで、仕事に行くんだよ! と言ったら、

「地下鉄や電車使わないで通えるところで仕事するから乗らない!!!!」 だって!。 爆笑。

その昔、通勤時間往復で4時間なんて無駄なことやっていた私。。。。通勤時間が1/3だったら、他の事にどれだけの時間を使えたことか。。。。。

姪が大きくなるころには、ソフトウェア開発や会議のために客先や、自分の勤める会社へ通勤する事無く、iChatAVのようなビデオ会議でミーティングを行い、自宅で開発するなどというスタイルが、一般的になっていると良いのだが。。。。。。。。。。

| | コメント (0) | トラックバック (0)

2007年5月 1日 (火)

DashCode Public Beta - Dashboard de OTN-J #10

前回のつづきです。
ひとまず、今回で、Dashboard de OTN-J widgetは完成です。

● Dashboard de OTN-J widgetでは、OTN-Jのforum全体のfeedだけを読込む widgetにしてあります。

以下のfeed URL固定です。
feed://otn.oracle.co.jp/forum/rss/rssmessages.jspa?categoryID=2

ただし、アプリケーションパッケージに含まれる、attributes.js にfeedのURLが定義されているので直接編集すれば変更することは可能です。(OTN-JのRSS2.0を対象にしています。また、rdfには元のコードが未対応で、atomも一部の情報は表示できません。)
feed urlを変更可能にしたり、atom対応など、OTN-J以外のfeedも表示するなどの version upは行うかもしれませんが、気分次第です。

以下、今回追加したコードの操作確認の模様。赤丸部分でマウスカーソルの形状変化させている。また、裏面では、URLの文字色を赤から黄色に変化させ、クリックすると、当ブログのトップページを開くようにしてある。(ハイパーリンクにすれば簡単なのだが、あえて、そのようにしてある。)

10_1 10_2 10_3
10_4 10_5 10_6

dashboard_de_otn.jsに追加したコード(一部抜粋)。
追加したコードは、マウスカーソル形状を変更するコードや、テキストの色を変更するコード、そして、裏面にあるblogのURLをクリックした際、該当blogをブラウザで開くといった細かい操作を行うためのコードを追加してある。

....中略....

/*****************************************************************
* added by mac de oracle  @2007/4/28                            */

function swapCursor(event)
{
if (event.type == "mouseover") {
document.body.style.cursor = "pointer";
} else if (event.type == "mouseout") {
document.body.style.cursor = "auto";
}
}

function swapTextColor(event)
{
if (event.type == "mouseover") {
event.currentTarget.style.color = "rgb(255, 255, 0)";
} else if (event.type == "mouseout") {
event.currentTarget.style.color = "rgb(255, 0, 0)";
}
}

function addMouseCursorListeners(element, callback)
{
element.addEventListener("mouseover", callback, true);
element.addEventListener("mouseout", callback, true);
}

function openMyBlog()
{
widget.openURL(this.innerText);
}

function addClickListeners(element, callback)
{
element.addEventListener("click", callback, true);
}

/* added by mac de oracle  @2007/4/28 
******************************************************************/

....中略....

function setHandlers()
{
var backOver = new Image();
backOver.src = "Images/backButton_over.png";
var backDown = new Image();
backDown.src = "Images/backButton_down.png";
var forwardOver = new Image();
forwardOver.src = "Images/forwardButton_over.png";
var forwardDown = new Image();
forwardDown.src = "Images/forwardButton_down.png";

var backButton = document.getElementById("backButton");
if (backButton) {
addHilightListeners(backButton, backOver, backDown);

// added by mac de oracle @2007/4/28
addMouseCursorListeners(backButton, swapCursor);
}

var forwardButton = document.getElementById("forwardButton");
if (forwardButton) {
addHilightListeners(forwardButton, forwardOver, forwardDown);

// added by mac de oracle @2007/4/28
addMouseCursorListeners(forwardButton, swapCursor);
}


/****************************************************************
***  added by mac de oracle @2007/4/28                       ***/

var blogURLText = document.getElementById("myBlogURLText");
if (blogURLText) {
addMouseCursorListeners(blogURLText, swapCursor);
addClickListeners(blogURLText, openMyBlog);
addMouseCursorListeners(blogURLText, swapTextColor);
}

var done = document.getElementById("done");
if (done) {
addMouseCursorListeners(done, swapCursor);
}

var refreshButton = document.getElementById("refreshButton");
if (refreshButton) {
addMouseCursorListeners(refreshButton, swapCursor);
}

var info = document.getElementById("info");
if (info) {
addMouseCursorListeners(info, swapCursor);
}

/*** added by mac de oracle @2007/4/28                      
***************************************************************/

}

ざっとこんなところ。。 javascriptのコードをこんなに書いたのも久々。。仕事以外では。。
ただ、javascriptのデバッガを搭載しているDashCodeのおかげで javascriptを久々に書いた
私でもそれほど苦労しなかった。。。便利になってきましたねぇ。ほんとうに!

ということで、ダウンロードはこちらから。dashboard_de_otn.wdgt.zip (216.5K)

参考として、DashCodeのテンプレートに手を加えていないオリジナルのWidgetもダウンロードして比べてみてください。 ダウンロード templete.wdgt.zip (119.7K)

| | コメント (0) | トラックバック (0)

2007年4月 2日 (月)

Mac De PL/SQL RSS Reader #33 (XSLT編 #5)

さて、前回からのつづき。

●プロシージャのソースです。

HTMLで表示しているため以下のソースをそのままコピー/ペーストするとコンパイルエラーなど不都合が発生することがあるかもしれませんので、ソースを利用される場合は、XSLTスタイルシートも含め、こちらからダウンロードしたソースをお使いください。 source.zip (3.9K)

CREATE OR REPLACE 
PROCEDURE RSS_READER_XSLT
(
i_feedXmlUrl IN VARCHAR2,
i_feedXmlCharset IN VARCHAR2,
i_styleSheetDir IN VARCHAR2,
i_styleSheetName IN VARCHAR2,
DEBUG_ IN BOOLEAN DEFAULT FALSE
)
AS
--===========================================================
rss_reader_xslt.sql : 2007/3/26 - Mac De Oracle
http://discus-hamburg.cocolog-nifty.com/mac_de_oracle/
--============ ===============================================

--============ TYPEs/VARIABLEs ===============================================
XSL_CHARSET_ CONSTANT VARCHAR(30) := 'UTF8';
v_feedXmlUrl VARCHAR2(32767);
v_feedXmlCharset VARCHAR2(30);
v_styleSheetDir VARCHAR2(30);
v_styleSheetName VARCHAR2(100);

myParser DBMS_XMLPARSER.Parser;
v_feedDoc DBMS_XMLDOM.DomDocument;
v_feedSourceClob CLOB;

myProcessor DBMS_XSLPROCESSOR.Processor;
v_xsl DBMS_XSLPROCESSOR.StyleSheet;
v_xslDoc DBMS_XMLDOM.DomDocument;
v_xslSourceClob CLOB;
v_xslDocFragment DBMS_XMLDOM.DomdocumentFragment;
v_transformedDoc DBMS_XMLDOM.DomNode;

v_clobbuffer CLOB;

--========== Internal PROCEDUREs/FUNCTIONs ===================================
PROCEDURE getXMLSource(
i_url IN VARCHAR2,
i_charset IN VARCHAR2 DEFAULT 'UTF-8',
io_sourceClob IN OUT NOCOPY CLOB
)
IS
v_httpReq UTL_HTTP.REQ;
v_httpResp UTL_HTTP.RESP;
v_xmlSource VARCHAR2(1024);
BEGIN
v_httpReq := UTL_HTTP.BEGIN_REQUEST(i_url);
UTL_HTTP.SET_HEADER(
v_httpReq,
'User-Agent',
'Oracle UTL_HTTP/Oracle10g R1;'
);

UTL_HTTP.SET_HEADER(
v_httpReq,
'Content-Type',
'text/xml;charset='||i_charset
);

v_httpResp := UTL_HTTP.GET_RESPONSE(v_httpReq);
DBMS_LOB.CREATETEMPORARY(io_sourceClob, FALSE);
BEGIN
LOOP
UTL_HTTP.READ_LINE(v_httpResp, v_xmlSource, true);
v_xmlSource := v_xmlSource || UTL_TCP.CRLF;
DBMS_LOB.WRITEAPPEND(
io_sourceClob,
LENGTH(v_xmlSource),
v_xmlSource
);
END LOOP;
EXCEPTION
WHEN UTL_HTTP.END_OF_BODY THEN
UTL_HTTP.END_RESPONSE(v_httpResp);
END;
END getXMLSource;

PROCEDURE drawFeedEntries(
i_buffer IN CLOB
)
IS
chunkSize_ CONSTANT PLS_INTEGER := 10922;
v_numOfChunk PLS_INTEGER;
v_src CLOB;
v_tempStr VARCHAR2(32767);
BEGIN
v_src := i_buffer;
FOR chunk# IN 0..CEIL(DBMS_LOB.GETLENGTH(v_src) / chunkSize_) LOOP
v_tempStr := SUBSTR(i_buffer, (chunk#*chunkSize_)+1, chunkSize_);
HTP.PRN(v_tempStr);
END LOOP;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(
'Error Occured : rss_reader_xslt.drawFeedEntries(CLOB).'
);
DBMS_OUTPUT.PUT_LINE(sqlerrm());
RAISE;

END drawFeedEntries;

-- for DEBUG
PROCEDURE pl(text IN CLOB)
IS
BEGIN
IF length(text)> 80 THEN
FOR i IN 1..(trunc(length(text)/80)+1) LOOP
dbms_output.put_line(substr(text,1+ 80*(i-1),80));
END LOOP;
ELSE
dbms_output.put_line(text);
END IF;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error occured : pl(VARCHAR2).');
RAISE;
END pl;

--
--
--****************************************************************************
-- Main
--****************************************************************************
BEGIN

v_feedXmlUrl := i_feedXmlUrl;
v_feedXmlCharset := i_feedXmlCharset;
v_styleSheetDir := UPPER(i_styleSheetDir);
v_styleSheetName := i_styleSheetName;

IF v_feedXmlUrl IS NULL THEN
RAISE_APPLICATION_ERROR(-20000, 'FEEDのURLを指定してください。');
END IF;
IF v_styleSheetDir IS NULL THEN
RAISE_APPLICATION_ERROR(
-20001,
'XSLTスタイルシートが保存されているディレクトリを指定してください。'
);
END IF;
IF v_styleSheetName IS NULL THEN
RAISE_APPLICATION_ERROR(-20002, 'XSLTスタイルシート名を指定してください。');
END IF;

-- RSS FEEDの取得する
getXMLSource(
i_url => v_feedXmlUrl,
i_charset => v_feedXmlCharset,
io_sourceClob => v_feedSourceClob
);
myParser := DBMS_XMLPARSER.NEWPARSER();
DBMS_XMLPARSER.PARSECLOB(myParser, v_feedSourceClob);
v_feedDoc := DBMS_XMLPARSER.GETDOCUMENT(myParser);

-- XSLTスタイルシートを読み込む
v_xslSourceClob := DBMS_XSLPROCESSOR.READ2CLOB(
v_styleSheetDir,
v_styleSheetName,
NLS_CHARSET_ID(XSL_CHARSET_)
);
DBMS_XMLPARSER.PARSECLOB(myParser, v_xslSourceClob);
v_xslDoc := DBMS_XMLPARSER.GETDOCUMENT(myParser);
v_xsl := DBMS_XSLPROCESSOR.NEWSTYLESHEET(v_xslDoc, NULL);

-- DOMにXSLTスタイルシートを適用する
myProcessor := DBMS_XSLPROCESSOR.NEWPROCESSOR();
v_xslDocFragment := DBMS_XSLPROCESSOR.PROCESSXSL(
myProcessor,
v_xsl,
v_feedDoc
);
v_transformedDoc := DBMS_XMLDOM.MAKENODE(v_xslDocFragment);
DBMS_LOB.CREATETEMPORARY(v_clobbuffer, FALSE);
DBMS_XMLDOM.WRITETOCLOB(v_transformedDoc, v_clobbuffer);

-- 変換後のHTMLを出力する
IF DEBUG_ THEN
pl(v_clobbuffer);
ELSE
drawFeedEntries(v_clobbuffer);
END IF;

DBMS_LOB.FREETEMPORARY(v_feedSourceClob);
DBMS_LOB.FREETEMPORARY(v_xslSourceClob);
DBMS_LOB.FREETEMPORARY(v_clobbuffer);
DBMS_XSLPROCESSOR.FREESTYLESHEET(v_xsl);
DBMS_XMLDOM.FREEDOCUMENT(v_feedDoc);
DBMS_XMLDOM.FREEDOCUMENT(v_xslDoc);
DBMS_XMLPARSER.FREEPARSER(myParser);
DBMS_XSLPROCESSOR.FREEPROCESSOR(myProcessor);

EXCEPTION
WHEN OTHERS THEN
IF v_feedSourceClob IS NOT NULL THEN
DBMS_LOB.FREETEMPORARY(v_feedSourceClob);
END IF;
IF v_xslSourceClob IS NOT NULL THEN
DBMS_LOB.FREETEMPORARY(v_xslSourceClob);
END IF;
IF v_clobbuffer IS NOT NULL THEN
DBMS_LOB.FREETEMPORARY(v_clobbuffer);
END IF;
DBMS_XSLPROCESSOR.FREESTYLESHEET(v_xsl);
DBMS_XMLDOM.FREEDOCUMENT(v_feedDoc);
DBMS_XMLDOM.FREEDOCUMENT(v_xslDoc);
DBMS_XMLPARSER.FREEPARSER(myParser);
DBMS_XSLPROCESSOR.FREEPROCESSOR(myProcessor);

IF DEBUG_ THEN
DBMS_OUTPUT.PUT_LINE('RSS Reader error:'||SQLERRM());
ELSE
HTP.TABLEOPEN();
HTP.TABLEROWOPEN();
HTP.TABLEHEADER('RSS Reader error:'||SQLERRM());
HTP.TABLEROWCLOSE();
HTP.TABLECLOSE();
END IF;
END RSS_READER_XSLT;
/


このサンプルは OTN-Jの CodeTipsでも公開しています。

(1/3) http://otn.oracle.co.jp/otn_pl/otn_tool/code_detail?n_code_id=2135
(2/3) http://otn.oracle.co.jp/otn_pl/otn_tool/code_detail?n_code_id=2137
(3/3) http://otn.oracle.co.jp/otn_pl/otn_tool/code_detail?n_code_id=2138

| | コメント (0) | トラックバック (0)