Outer Apply
今日はゆるゆるだったから、
というか午前中は全ビルドが通らずそのまま潰れ、
午後から作業開始という感じだった。
どうやらVSSが悪さ?をしているらしく、
VS.NETでビルドするとローカルではなく、
VSS側のライセンスファイルを見る為に、
ローカルソースとライセンスで差異が発生して弾かれてたみたい。
そんな事をいっていたSz*1さんはカッコいいと思っていたが・・・
午後になると、隣で私に対する私語か独り言か分からないトーンで、
色々と話しかけてきた。
「ここの仕様は?」とか、「あ〜また出たあー」とか、「これ、どういう意味?」とか・・・。
『うぜえよ!』
本当に!気が散るどころか作業の邪魔するなよなあ(怒
全く進まず、だから今日は私的に緩々でした。
定時後に『飲みに行こうぜ』と誘われ、
お客さんに頼まれたストアドの修正をしていると、
私が四苦八苦してなかなか進まない事に腹をたてたらしく、
横で『なんで俺をイラつかせるんだ?イライライライライラ・・*2』
散々、邪魔しといてそう急かすなよ!
『うるさいっ!一人で帰れ!!』とか、のど元ぐらいまで出掛かったが、
私は大人・・というか、お客さんの前でそんな愚態を見せられる訳もなく、
『すみません、私は欠席で・・』とか言ったけど、
『え〜??お前も来るんだよお』とピッタリと隣をマーク*3
てか、ストアド、いやデータベースっていまいちよく分からないんだよな。
プログラムだったらデバッグで追えるけど、
ストアドとかテーブルが沢山連なったSQLとか、
どこをどう見て良いのか分からん。
本やネットでもデバッグテクみたいなのがないから、本当に分からない。
まあ、結局は業を煮やしたSzが、
ヒントといいつつ、結局は解答を解説。そして修正、デバッグ*4
Ctrl + K,K と Ctrl + K,N で
青いブックマークみたいのがVS.NET上のエディタで置けるらしい。
ちょっと、今アルコールのせい(?)でよく覚えていない・・
問題だったのは、
テーブルを幾つかつなげるSQLのうち、
Outer Apply*5をしている部分が原因だったようだ。
アウプラはネットで調べても出てこないし*6、
会社のSQLバリバリ書く先輩に聞いても、「知らない」といわれるぐらい
マニアックなもののようだ。私の持ってるSQLリファレンスにも乗ってないし。
要は連結したテーブルの項目をそのままアウプラに渡せる。
つまり連結したテーブルから検索項目を取り出して、
それをなんらかの関数に渡した戻りのテーブルとつなげたりできる。
イメージ的には1行のレコードずつに関数からの戻りテーブルをつなげることができる。
あ、そお。『Left Outer Join*7』と何が違うのさ。とか思ってるんだけど、
Sz曰く、処理速度に差が出てくるようだ。
レフジョの場合、全てのテーブル(関数の戻りテーブルを含めて)を連結した後に、
Where句またはOn句の条件で絞り出す流れとなる。
しかしアウプラの場合は、関数の戻りテーブルが、ある引数のパターン*8によって、
1レコードしか返ってこないとすると、
つなげる時に全てをつなげて条件絞り→1行のレコードをつなげるだけとなり、
速度の向上が見込めるとの事らしい。
へえ〜としか言えないが、
プログラムと違ってSQLは書き方次第で処理速度が天と地の差になる事は、
今回のプロジェクトで分かっているので、実感はできる*9
それ以前に、
SQLで連結した項目を同一SQLクエリ内の関数に引数で渡せない事を知った方が、
私にとってもインパクトはあった*10
ただし、アウプラにも注意する事がある。
それはOn句みたいなのが使えないので、
関数ではなく、
純粋にテーブルの連結となると条件が追加できない為フルジョインになってしまう。
つまり左1行に対して、つなげる先分が追加されるので、
つなげる元の左側レコードがつなげる先分増えることになる。
今回のバグはまさにこれで、
関数に渡す引数にNULLが含まれる連結元テーブルが存在し、
その関数が1行返すのではなく、
全部返すようになっていた。
そりゃあ、出力されるテーブルの行数が数倍に跳ね上がるさ。
便利だけど使う時は注意が必要なアウプラでした。
その後は近くの居酒屋とパブ的なところ*11に行き、
色々と職場や今の仕事、周りの人の現状、不満なんかを言っていた。*12
Szが『俺に対してなんかないのか(笑』的な事を言っていたが、
『いえるはずがなかろう!』
とりあえず、アルコールをグビグビのんで、日ごろ*13のストレスを発散した。
なので今は体がダルい。
アルコールのせいか体*14の筋肉に乳酸的な疲労感があります。
だから今日はこのぐらいにして、また明日*15