ソフトウェア開発者の日常

こだわりなく書きたいことを書いていきます。

SQL Server からのデータ取得でエラーになった理由

SQL Server Management Studioでデータ取得のクエリを作成しました。
同じテーブルに別名をつけて何度も結合したり、CASE式があったりとややこしいクエリです。

PHPでデータを取得して処理するので、作成したクエリを実行できるようにソースコードに貼り付けました。
実行したところ、なぜかエラーが発生しました。

思ってもいないところでエラー発生

PHPからSQL Serverに対して直接データを取得するわけではなく、PEAR::DBを利用してデータを取得しています。
PEAR::DBがエラーを出力していましたが、クエリのどこがエラーの原因なのかまではわかりません。

どうやって調べるか少し悩みました。
やみくもに直感だけでクエリを修正しても回り道になるだけなのです。
手間はかかりますが、結合するテーブル1個ずつ増やしながら、どこでエラーになるのか探すことにしました。
f:id:AJYA:20160805054727j:plain
photo credit: Michael Donnelly at SQL Saturday via photopin (license)

結合するテーブルを1個ずつ増やしていきますが、エラーは発生しません。
全ての結合するテーブルを結合するようにしても、エラーは発生しませんでした。

次にSELECTに続いて記述する、データを取得するカラム名を増やしていきました。
結合したテーブルのカラム名をすべて記述しても、エラーは発生しません。

ここまでエラーが発生しなくて、どういうことだと思いました。
残るのは、結合先のテーブルのカラム名の記述を追加するしか、SQL Server Management Studio上で作成したクエリとの違いはありません。

結合先のテーブルのカラム名の記述を追加していくと、エラーが発生しました。
追加してエラーが発生したカラムの定義を見てみると、ntext型になっています。
ここになにか特有なことがあるようです。

今回のプログラムは、5年以上前に開発されたシステムに対してのプログラムの追加です。
既存のソースコードカラム名で検索してみました。

検索した結果、既存のソースコードは、

SELECT table1.comment, (省略)

ではなく、

SELECT cast(table1.comment as text) as comment_text, (省略)

のようにCASTされていました。

これで動作するのかと思いつつ、同様に記述するとエラーは発生しなくなりました。

SQL Server Management Studioで動作するからといって全ては動作しない

既存のシステムが動作している環境だったので、検索して解決策を見つけられました。
最新のPEAR::MDB2Microsoft Drivers for PHP for SQL Serverを使えばCASTしなくてもエラーは発生しないのか、機会があれば調べたいです。