BLOGスタッフブログ

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のバージョンアップで対応されていればいいんですが、そうでない場合は注意したほうがいいですね。

上松 博志が書いた他の記事

見積もり・ご依頼など、
お気軽にご相談ください

本サイトはユーザーエクスペリエンスの向上などを目的に、Cookieを使用しています。
右記のバナーで「同意する」をクリックする、または本サイトを利用することにより、
お客様は弊社のCookieポリシーに同意したことになります。

同意します