« PL/SQL で Python Challenge 8 | トップページ | PL/SQL で Python Challenge 9 簡単でした »

2005年7月25日 (月)

PL/SQL で Python Challenge 8完結編

Python challenge Level8 を解いてみた。 PL/SQLJavaOracleを使って解くと結構大変なことも多々あるなぁ。。。それを承知でやっているのではあるが。。。(^^;;;

Python challenge Level8のヒントは前回の通り、「ブンブン蜂が飛ぶ。その音」(もちろん英語で)。

Python Global Module Indexにあるどのモジュールを利用するのかがわかれば簡単で、Pythonでは3行で解けてしまった。
しかし、PL/SQL+Java+Oracle10g では手こずった。プログラミング以前に、PL/SQLJava(J2SE)にもPythonのモジュールに該当するものがないのである。
検索したところ、Apache Antプロジェクトに同じ機能を持つpackageがあることを発見した。(Ant全体ではなく該当部分だけが jar として公開されていたのでそれを利用することにした。)
そのページのNOTE部分には大事なことが書いてある。それを読まないで該当packageを利用するとハマるので注意。(私はまる一日ハマってしまった)ネタバレになるので、そのページのURLは書かない。自分で探してもらいたい。

今回は、以下のように level8 というPL/SQLパッケージを作成した。(Level7と同様に、MacOS X Panther 10.3.9にインストールしたOracle10g 10.1.0.3 を利用している

SQL> desc level8
FUNCTION GETANSWER RETURNS VARCHAR2
FUNCTION GETPS RETURNS VARCHAR2
FUNCTION GETBLOBSOURCE RETURNS BLOB
引数名 タイプ In/Out Default?
------------------------------ ----------------------- ------ --------
SOURCE VARCHAR2 IN
FUNCTION GETUN RETURNS VARCHAR2

SQL>

PL/SQLのコードはネタバレになるのでいつもの通り非公開だが、作成手順やネタバレにならない程度の概要は書いておく。

getUn() 関数と getPs() 関数は、Level8の問題そのものを取得するPL/SQLだけで記述した関数である。長い文字列なので入力の手間を省く為にPL/SQL package中のプライベート定数としてあり、その文字列を取得するだけの関数である。。
コード量は、それぞれ数行程度だった。


getBlobSource() 関数は、getUn()関数、getPs()関数の戻り値を入力して、加工後、BLOBとして返す。これもPL/SQLだけで記述した関数である。どんな加工を行ったのか詳細は書かないが
エスケープシーケンスを含む文字列を処理したとだけ書いておく。Oracleでは特定の関数などで
エスケープシーケンスを利用するものがあるが、それ以外では通常の文字列として扱われるのでこの処理がポイントになるのではないかと思う。Oracle10g新機能である正規表現関数はすべて利用した。
コード量は、20行程度だった。


getAnswer() 関数は、getBlobSource()関数を呼び出し、戻り値から解答を取り出だすjava stored function としてある。この関数はラップされている method内で、Apache ant
に含まれているあるpackage ( jar ファイルは該当package分だけ入手可能 )を利用している。
javaのコード量は、60行〜70行程度だった。


手順も書いておく。
  • 1.入手したjarファイル(Apache antの該当packageだけの jar)を loadjava コマンドを利用して、Oracleにロードする。 

  • 例) jarファイル名などは隠してあります。(それを見せたらネタバレなので)
    cube: oracle$ loadjava -v -user scott/tiger xxxxx.jar
    arguments: '-v' '-user' 'scott/tiger' 'xxxxx.jar'
    identical: META-INF/MANIFEST.MF
    identical: org/apache/xxxxxxxxxxxxxxxxxxxxxxxxxxxx
    identical: org/apache/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    identical: org/apache/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    identical: org/apache/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    identical: org/apache/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    identical: org/apache/xxxxxxxxxxxxxxxxx
    identical: META-INF/LICENSE.txt
    cube: oracle$

  • 2.getUn()、getPs()、getBlobSource()までをPL/SQLだけで実する。

  • 3.getAnswer()でラップする java classを実装及びテストする。

  •  1のjarファイルはライブラリとして必要。(このclassで、getBlobSource()を jdbcを利用して実行する)。 

  • 4.3で作成した classを loadjavaまたは、JDeveloper10g Developer Preview for MacOSXで、データベースにロードする。
  • level8_jdev

    以下、実行結果のスナップショット(いつものように答えは隠してある)。
     level8




    Level9へつづく。

    |

    トラックバック


    この記事へのトラックバック一覧です: PL/SQL で Python Challenge 8完結編:

    コメント

    コメントを書く