2012年1月25日水曜日

SQLメモ

いつも忘れるのでメモ。
日付がYYYY,MMと別項目に数値タイプで入っている場合、
たとえば2001年1月以降のデータを抽出したい時がある。
簡単にすますと、
SELECT * FROM MASTER M
WHERE
M.START_Y * 100 + M.START_M >= 200101
なんてやってしまいがち。でも、これだと、START_YとSTART_Mにインデックスが張られていても、
使用されない。
インデックスを使用するようにするには、計算させなければ良いので、以下のように書き換える。
SELECT * FROM MASTER M
WHERE
(
  (M.START_Y > 2001)
 OR
 (M.START_Y = 2001 AND M.START_M >= 01)
)
応用編として、
M.START_Y * 100 + M.START_M BETWEEN 200004 AND 200103を書き換えてみる

(
  (
   (M.START_Y > 2000)
   OR
   (M.START_Y = 2000 AND M.START_M >= 04)
  )
  AND
  (
   (M.START_Y < 2001)
   OR
   (M.START_Y = 2001 AND M.START_M <=03)
  )
 )
可読性は落ちるけれど、これでインデックスが使用されるようになる。

2012年1月7日土曜日

PHP5技術者認定初級試験を受けてみた

PHPカンファレンス2011で受験資格が当たったので、受けてきました。

PHPは、学生時代にPHP4をやった程度で、社会人になってからは本業でないこともあり、
すっかり遠ざかっておりました。

まず、受験に当たり、過去問を繰り返し、一通り解きました。
出題範囲はここにあるように、『初めてのPHP5』を主教材とし、一般的な知識やPHPオンラインマニュアルなどからも出題します。主な対象バージョンはPHP5.3です。(2011年9月現在)
とのことなので、本を購入しようか悩んだのですが、昔やっていたこともあり、まぁ何とかなるだろうと高をくくっていました。

で、受けてきました。


会場へは30分前に到着。席が空いているとのことで、予定よりも早く受験できました。

結果は77点でなんとか合格。
80点は堅いと思っていただけに、ちょっとショック。まっ実力なんてこんなものです。
ちなみに、過去問で出た問題は一問も出てこなかった。

ちゃんと本で勉強しておけば良かったと出だしから躓く。
試験時間は60分で、問題は全部で40問。時間は見直しも含めてちょうど良い感じ。
前半は初級試験と言うこともあり、基本的な問題ばかり。
(PHPはプログラム言語か?みたいな問いとか)
前半戦はPHPじゃなくても何かプログラム言語を知っていれば解けると思う。
後半戦は残り時間が気になるのもあるけれど、難易度が上がり、若干焦る。

たとえば、テーブルにデータをINSERTし、UPDATEした上で、特定行をDELETEし、
残りをSUMしたら幾らになりますか?とか。(PHP関係ないじゃん。)
PHPの試験なのに、PEAR::DBとかPEAR::MDB2とかPDOとか出てきます。
(PEAR::MDB2のコールバックなんてフレームワーク使っているととっさに出てこない。)
セキュリティ関連の問題は、前提条件の記載がないので、選択肢が間違っていると言えなかったり。(たとえば、セキュリティのために入力チェックをすればいいとあっても、それだけでは駄目だし、そもそもセキュリティのために入力チェックする訳ではないし。)

試験が終わると、すぐ結果がコンピュータ上に表示され、後でレポートを受け取ります。
このレポートには、セクション別正解率がのっていますが、どの問題が間違えたかは載っていません。


自分が間違えたと思う箇所(問題まるまる乗せると不味いので、ニュアンスが変わらない程度に変えています。)
・ ereg_replaceとpreg_replaceの違いについて(とっさに出てこなかった)
・ ob_start()がネストできるかどうか。(普通ネストしないし)
・ 動的にSQLを組み立てる場合はDB接続前にmysql_real_escape_stringでエスケープする。(問題文の意図がよく分からなかった。DB接続前にmysql_real_escape_stringしたら、直近のDBに接続するのではなかったっけ?)
・ PHPのファイルオープンはサーバの権限に依存しない。(リモートファイルを開く場合は相手先のサーバの権限なんて関係ないと思うのだけれど。PHP.INIの設定には依存すると思うけれどね。)
・ 日付・時刻関数及び書式設定について(暗記する物でもない気がする。)

試験で難しいのは、問題の日本語(の解釈)が難しい。PHPは似たような機能を持った関数が多いので、普段使わない関数の引数とか覚えていない。フレームワークに甘んじて素のPHPの挙動を忘れかけている。0とFalseとnullは同じとか、関数によって帰ってくる値が0かFalseか統一されていないといった、変態な動作正しい動作を思い出しておきましょう。(こんなサイトがあるんですね。)
問題文の解釈は難しかったです。たとえば、以下のプログラムで正しく処理できるように(1)を埋めなさい。と言う問題で、
if ((1)) {
die("エラー");
}else{
・・・・・・・
}
で、選択肢として
$foo == falseと$foo == trueがあった場合(実際には$fooは値がセットされている)、どちらを選んでも正しく処理されるよね?
問題文にはエラーが出ないようにとか・・・・・・・の処理が走る時とかの記載はなし。
多分エラーが出ない方が正解だと思うけれど。

妙な引っかけ問題も注意。しかも割と多い。
たとえば、
$hoge="hogehoge";
echo "Foo :" .$hoge;
で出力される文字はhogehogeである。とか。正解はFoo :hogejoge(実際のコードはもう少し長く複雑です)

define("CONSTANT", "Hello world.");
define("CONSTANT", "Hello Mic.");
define("CONSTANT", "Hello Eriko.");
echo Constant;

で出力される文字は?ただし、エラーは無視する。(正解はConstantです)

総評として
・問題の難易度がばらついているなぁと。
前半の問題が基本的な点を問うているのに対し、後半の問題が暗記問題というか重箱の隅をつつくというか、無理矢理作りました感がある。プログラムは暗記問題ではないので、日付関数の書式を問うたり関数の引数や返値を問うのはちょっと違うのでは?
・プログラムの穴埋め問題は、問題の性格上意図的に見難いプログラムなんだろうけれど、そこは本質じゃないと思う。本質は正しい動作をするように適切な処理を選択させるのであって、わざわざ見難いプログラムにする理由はないと思う。
・初級試験なら、PHPの動作(たとえばis_numericは数字以外にも数値形式の文字列もOKとか)に関する基本事項をもっと出しても良いと思った。
・セッションやクッキー、フォーム処理や日本語処理、URLの扱いなどはPHPでWebアプリを作る場合ほぼ必須なので、もっと出題数を出しても良いと思う。urlencodeとかurldecodeとかは(自分の時は出なかったけれど)お作法として押さえておくべき。