今回の患者さんは、<cfoutput>でデータベースから集計した値を表示しようとして、悩んでいるようです。どれどれ、、、
<cfquery datasource="cfartgallery" name="qArtCount"> SELECT Count(*) FROM ART </cfquery> <cfoutput query="qArtCount"> #qArtCount.??????# </cfoutput>
なるほど。データベースからデータは取得できましたが、その後、どうやって呼び出せば良いかが分からず悩んでいるようですね。
ColdFusionは、SQL文をそのまま使えるのが利点と言われていますが、Count やMax, Sum, Avg など集計・集合関数を使っている場合、その結果をColdFusionで表示するにはどうすれば良いでしょうか?
ポイントは、ColdFusionのクエリ変数のデータ構造です。ColdFusionはカラム名を使用して対象の列のデータを取得しています。ただ、今回のように集計・集合関数を利用した場合、その結果にはカラム名が含まれません。
もうひとつ、似た様なサンプルをご紹介します。下記は、データベースのP1Dataテーブルからデータを取得していますが、P1テーブルの列は「art name, price」と、“art name”の列名にスペースが含まれています。
<cfquery datasource="****" name="qP1Data"> SELECT * FROM P1 </cfquery> <cfdump var="#qP1Data#">
この場合も、<cfoutput query="qP1Data">#qP1Data.art name#</cfoutput>と書くと ColdFusion の構文エラーが発生し、呼び出すことができません。
このように列名によって問題が発生する場合、その最も良い対処は SQL 側で問題が発生する集計結果や列の名前に対して「別名」を付けることです。
SQLで別名の指定には AS というキーワードを指定します。最初のコードの例では、集計したCount(*)の結果に対して 「AS 別名」を付加してあげれば、問題を解消できます。
<cfquery datasource="cfartgallery" name="qArtCount"> SELECT Count(*) AS ArtCount FROM ART </cfquery> <cfoutput query="qArtCount"> #qArtCount.ArtCount# </cfoutput>
2番目のコード例では、SELECT "art name" AS ArtName, Price From P1Data のように設定します。ただ、データベースによっては二重引用符で囲む方法ではエラーが発生するかもしれません。その場合は使用しているデータベースのSyntaxをご確認下さい。
問題の発生する列名ってどんなの?って思った方は、ColdFusion の変数名を付ける際の命名規則を思い出し、実行するSQLで命名規則に違反する列名や集計・集合関数の場合には、ASによる別名を付けるというルールでプログラムを行ってみて下さい。
厳密に言うと、今回の問題が発生する列に別名を付けなくてそのまま呼び出す方法もあります。
最初の例は、クエリ変数を<cfdump>してみると列名の部分に数字の1が入っています。つまり、#qArtCount.1# と指定すればデータを呼び出せます。
ただ、プログラムコードのメンテナンスの面から考えて、「#qArtCount.1#」が一体何を指すのか?が分かり辛いのは明らかです。
2つ目の例はもっと複雑で、クエリ変数を「構造体&配列」のような記述で呼び出す方法となります。
<cfoutput query="qP1Data"> #qP1Data["art name"][qP1Data.CurrentRow]# <br> </cfoutput>
この場合も、後からプログラムの面を考えると、ASによる別名を付けた方が確実に分かりやすいでしょう。
ASによる別名は、複数のテーブルで同じカラム名があった場合などで、列名を明示的に区別する方法としても有効な機能です。長いカラム名を短い別名にするのも良いでしょう。SQLで補えるところはSQLで行い、ColdFusion側のコードのメンテナンス性を上げる手段としても有効ですので、ぜひご活用下さい。