トップページ 本棚 メモ帳 告知板 道具箱 サイトの表示設定 リンク集 Twitter

テーブル結合時に列別名を付けなかった場合

Tags:

列別名が付いていない場合に起こり得る現象

具体的な原因は不明だが、複数テーブルを結合した上で特定の列のみをSELECT文で抽出した場合、PHPで処理する際に値が上手く取り出せないケースがある模様。

SELECT
	A.tag
	,B.contentID
	,B.titleText
FROM
	tagTable A
	INNER JOIN
		entryTable B
		on
			A.contentID = B.contentID
WHERE
	(省略)

上のSQLを実行した場合、結果として「A.tag」「B.contentID」「B.titleText」の列からなる連想配列のセットが得られるが、どうもこの時連想配列のキー名としてtagではなくA.tagが設定されてしまう? ようで、その後の処理で$resultSet[0]['tag']などとしてもテーブルに格納された値が取り出せない。

しかし不可解なことに値は取り出せないがエラーにはならず、空文字で正常に(*1)処理が行われてしまう。連想配列からの値取り出し時に存在しないキーを指定した場合は確実に警告されるはずなのにそれが発生しない。

さらによく分からないのが、この時ローカル環境では正常に値を取り出せるが、リモート環境(*2)で動かすと値が取り出せない事象が起きた。ローカル環境はPHP 7.4.7、リモート環境はPHP 7.4.10。データベースエンジンは両者ともSQLite。何に起因しているのかさっぱり分からない。

なおSQLiteをコンソールで立ち上げて.headers onをセットしてから直接SQLを実行した場合、ヘッダ名にはテーブル別名は付与されない。単純に列名が表示される。ますます謎。

コマンドプロンプトでの実行画面。

一つ言えるのは、as句で別名を付ければ回避できるということ。

SELECT
	A.tag as tag
	,B.contentID as contentID
	,B.titleText as titleText
FROM
	tagTable A
	INNER JOIN
		entryTable B
		on
			A.contentID = B.contentID
WHERE
	(省略)

ひとまずテーブル結合をするときには列に必ず別名を付けることにするが、意味不明すぎるのでもう少し深掘りしたいところではある。

追伸

リモート環境の方はSQLiteのバージョンがかなり古いものだった(*3)。リリースノートなどは追い切れていないものの、これが原因になっている可能性はありそう。

*1:予期しない動きをしているので異常なのだが、PHP的にはエラーではないという意味。
*2:端的に言うとさくらインターネットのサーバ。
*3:アレな感じなので具体的なバージョンは伏せるが、割とビックリするレベルで古かった。