2014.02.17 システム
PHPでPDOを利用する場合に、おかしな現象が発生することがあります。ari
PHPでPDOを利用する場合に、おかしな現象が発生することがあります。
(おかしな現象が発生したのは、PHP5.2.13・mySql5.1.60です)
このおかしな現象は、下記のような結合SQLを実行した場合に発生します。
SELECT<br>
t999.id AS id<br>
,t999.name AS name<br>
,m001.name AS name01<br>
,m002.name AS name02<br>
,m003.name AS name03<br>
,m004.name AS name04<br>
FROM<br>
hogehoge_main AS t999<br>
INNER JOIN master_01 AS m001<br>
ON t999.m1code = m001.code<br>
INNER JOIN master_02 AS m002<br>
ON t999.m2code = m002.code<br>
LEFT OUTER JOIN master_03 AS m003<br>
ON t999.m3code = m003.code<br>
INNER JOIN master_04 AS m004<br>
ON t999.m4code = m004.code<br>
WHERE t999.id = 123456<br>
何の変哲も無いSQLです。
このSQLを各種のSQLクライアントで実行すると…
|id | name | name01 | name02 | name03 | name04
-+—+————–+———-+——–+———-+———
|01 | マリンロード | デザイン | +EC | システム | セールス
こんな感じの結果が取れました。実に普通ですね。
それではプログラムに組み込んで実行してみましょう。
|id | name | name01 | name02 | name03 | name04
-+—+————–+———-+——–+———-+———
|01 | マリンロード | デザイン | +EC | null | セールス
なんと、name03が取れなくなってしまいました…。
ですが、SQLクライアントで実行した結果は正常です。
SQLには問題はなく条件も入っており、何も問題無いように見えます。
この現象の原因は、「master_03テーブルとの外部結合が内部結合中に混じっているから」でした。
SQLクライアント上はちゃんと動いているのに、どうしてこうなるのやら…
PDO上でどういう解釈をされているのかわかりませんが、内部結合と外部結合が混じったSQLでこの現象が発生するようです。
上記の問題を解決する方法は、外部結合を内部結合の後にすることで解決します。
SELECT
t999.id AS id
,t999.name AS name
,m001.name AS name01
,m002.name AS name02
,m003.name AS name03
,m004.name AS name04
FROM
hogehoge_main AS t999
INNER JOIN master_01 AS m001
ON t999.m1code = m001.code
INNER JOIN master_02 AS m002
ON t999.m2code = m002.code
INNER JOIN master_04 AS m004
ON t999.m4code = m004.code
LEFT OUTER JOIN master_03 AS m003
ON t999.m3code = m003.code
WHERE t999.id = 123456
SQLの解釈上の問題のようですが、こんなおかしな挙動をするのは予想外でした。
こんな現象、実際の本番環境で発生したら原因特定できないでしょうね。
PHPのバージョンアップで対応されていればいいんですが、そうでない場合は注意したほうがいいですね。