ビューを調査する(oracle)
はじめに
Oracleで便利なビューが沢山あると楽だけど、謎のノウハウやら得体の知れない仕様を詰め込まれたビューを引き継いだ場合はなかなか厄介だ。
ファンクション、プロシージャ、トリガーよりすこし癖のある調査が必要となるビューの調査方法について備忘をかねて記述しておく。
再確認
バージョン管理システムにビューの最新のソースや最新のドキュメントが登録されているかを調べる。それらが見つかれば以下の作業は必要ないはず。
ビューのソースを参照
Oracleではファンクションやプロシージャ、トリガーのソースを調べるときは「user_source」を参照すれば良い。
SELECT text FROM user_source WHERE name = "名称" ORDER BY line
ところが「user_source」にはビューは含まれていない。ビューの情報を持っているテーブル「user_views」を参照する必要がある。
SELECT text FROM user_views WHERE view_name = "名称"
依存関係
沢山のビューの中から、特定のオブジェクトを参照しているビューを洗い出すには「user_dependencies」を調査するほうが「user_views」の中身を見ていくより速い。
SELECT name, referenced_type, referenced_name FROM user_dependencies WHERE type = 'VIEW' AND referenced_name = "参照されているオブジェクトの名称"
マジックナンバーの埋め込みを調査するには?
マジックナンバー使ったり、さらにDECODEで条件分岐などのロジックを埋め込んでいるようなオブジェクトを洗い出す必要がある場合にはどうするか。
ビュー以外の場合は以下の方法で検索できるが
SELECT name, line, text FROM user_source WHERE text like "%マジックナンバー%" ORDER BY line
ところが調査対象であるビューのソースを保持している項目「user_views.text」の属性は「LONG型」だ。
これは最大長の大きいVARCHAR2型みたいなものだけど、where句で使えない制約付の型なので「user_source.text」を検索する場合のような扱いは出来ない。
どうするかというと簡単なスクリプトを作成して調査する。
以下の例はrubyでアドホックに作ってみたスクリプトだ。
#!/usr/bin/env ruby require 'oci8' oracle = OCI8.new('ユーザID', 'パスワード', 'データベース名称') oracle.exec("select view_name,text from user_views") {|view_name,text| text.split("\n").each { |line| if ARGV.length != 0 then ARGV.each{ |magic_no| if (line.index(magic_no) != nil) then puts "\""+ view_name + "\",\"" + line.chomp + "\"\n"; end } end } }
やっていることは単純で、
- 全ビューを検索対象として
- ソースを改行コード毎に調査
- それが引数で渡したマジックナンバーにマッチするかを調べる
- 該当した場合はビュー名称と該当ソースを出力する
ことくらい。
これを適当な名称をつけて
>スクリプト名 マジックナンバー
で実行すれば、マジックナンバーを利用しているビューのリストが取得できる。
マジックナンバー利用はあまり有益じゃないのでリファクタリング可能ならしておくこと。
おわりに
調査後ソースをバージョン管理するなりドキュメントを整理してプロジェクト内でも管理体制を周知しておくと、後々引き継ぎした人が助かるだろう。