SQLは、よく使われるプログラム言語に比べると、かなり短い記述で複雑なデータ検索処理を書けますが、構文エラーが発生すると、どこが間違っているのか解析するのが面倒です。
今回は、そのようなSQLの構文エラーを、効率よく探す方法や、探す際の考え方などを紹介します。
SQLの構文は簡単そうで実は難しい
JavaやPHP、C++などの多くのエンジニアが使っているプログラミング言語を学んだ方にとって、SQLはかなり異質な言語です。
簡単な記述でより、全て自動で処理してくれるので、一見便利そうに見ますが、構文エラーが出ると、どこで間違ったのか探すのが面倒です。まずは、SQLの構文エラーが難しい理由を説明します。
複雑な検索処理を1行で書ける
SQLの特徴は、1行の比較的短い記述で、かなり複雑なデータ検索処理が書ける点です。これは、SQLのメリットですが、構文エラーを解析する場合は、デメリットに変わります。
例えば、プログラミング言語で構文エラーが発生した場合、それが何行目で、どういったエラーかが表示されます。
しかし、1行で書けてしまうSQLで構文エラーが発生した場合、どの辺りでエラーになったかしか解りません。これが、SQLの構文エラーの際のデバックを難しくしている理由の1つです。
書かれた順序で評価されていない
SQLは、コンピュータの動作を気にせずに、短い記述でデータの検索処理が書けるプログラミング言語と言えます。ただし、実際には、SQLを評価し、データベース管理ソフト内部で処理スケジュールを作り、それに基づいて複雑な検索などを実行しています。
そのため、SQLを書かれた順序で評価している訳ではありません。SQLの後ろの方の構文エラーを修正したのに、前の方で再度構文エラーが見つかることも珍しくありません。
何度も前と後ろのステートメントの構文エラーを直しているうちに、想定した検索と違ってしまうこともあります。
データベース管理ソフトによって使えるステートメントが違う
SQLは、国際標準のSQLが決められており、SQLが使えるデータベース管理ソフトでは、国際標準に準拠しています。しかし、それぞれのソフトが独自に拡張した機能が多く、さらに、同じ機能でも違うステートメントを使用ケースがよくあります。
そのため、違うデータベース管理ソフトで動作していたSQLをコピーしたら、構文エラーになって動作しない、ということはよくあります。そのような場合は、マニュアルをチェックして、正しいステートメントを使わなければなりません。
SQLの構文エラー箇所の探し方
プログラミング言語の学習で、つまずく原因になりやすいのが、なぜ、このエラーメッセージの出るのか解らないケースです。これは、SQLの構文エラーのメッセージにもあてはまります。
次から、SQLの構文エラーで困ったことが多い方に、その探し方をアドバイスします。
適度に改行を入れて見やすくする
SQLは、SELECTやUPDATEなどから、「;」までが1つの命令です。そのため、検索で使われるSELECT文は、どんなに複雑でも、最初のSELECTから終端の「;」までを1行で書けてしまいます。
しかし、そのようなSQLで構文エラーが発生した場合、エラー箇所を探すのは大変です。このように読みにくいSQLを扱う場合は、ステートメント毎に改行し、読みやすくしてみてください。
1行で書いたSQLの例 SELECT * FROM table_one WHERE (( 部門=10 OR 部門=11 ) AND 役職=1 ) ORDER BY 社員番号;
ステートメント毎に改行を入れた例 SELECT * FROM table_one WHERE ( ( 部門=10 OR 部門=11 ) AND 役職=1 ) ORDER BY 社員番号 ;
クライアントツールで実行してみる
多くのWebシステムで、データベース管理ソフトを利用しています。そのため、プログラム内でSQLを作成し、それでデータの更新や検索を実行するケースがよくあります。このような場合、SQLの構文エラーが発生しても、どこがエラーなのか解りません。
こういったケースでは、プログラムで作成されるSQLを取り出し、データベース管理ソフトのクライアントツールや、グラフィカルな操作ができる管理ツールで直接実行してみてください。
簡単な構文エラーなら、この方法で、すぐに見分けがつきます。そのため、クライアントツールや管理ツールの操作にも慣れておきましょう。
SQLを分解して実行する
SQLは、サブクエリーを複数組み合わせる複雑な検索処理だとしても、1つの命令文です。複雑なSQL文で構文エラーが発生した場合、どこにエラーがあるかを調べるのは、ベテランでも簡単ではありません。
SQLのSELECT文では、多くのステートメントが使えますが、特定のステートメントに続けて使うものもあります。このような長いSQLから構文エラーを探す場合、最低限必要なステートメントのみにSQLを分解して実行してみてください。
そして、1つ1つステートメントを追加していけば、構文エラーの箇所を調べられます。
構文チェックを利用する
一般的なプログラム言語では、構文チェックのためのオプションや、専用のチェックツールなどが利用できます。そして、SQLにも、その構文をチェックするツールやWebサイトがあるので利用してください。
一般的なプログラム言語と同じように、構文エラーの原因は、簡単なスペルミスや括弧を閉じるのを忘れたケースなどがほとんどです。このようなエラーは、構文チェックを利用することで、簡単に見つけらます。
なお、SQL構文チェックは、プログラム開発に使われる統合開発環境(IDE)に備わっていることが多いので、チェックしてみてください。また、SQLの構文チェックが可能なWebページもあります。
MySQL構文チェッカー:MySQLコードの構文エラーをチェック | ラッコツールズ
構文エラーを出さない工夫
先ほど、構文エラーを探す方法を紹介しましたが、構文エラーを探すよりも、構文エラーを作らないように工夫すべきです。次から、構文エラーを出さない方法について紹介します。
構文チェック付きエディタでチェックする
JavaやPHP、C++など、よく使われているプログラム言語でシステムを開発する場合、通常、統合開発環境(IDE)を使います。そして、IDEの最大のメリットは、プログラム開発を支援する機能が付いている点です。
そのため、IDEの構文チェックを利用したり、ステートメントを候補の中から選ぶ機能を活用することで、スペルミスや構文エラーを防げます。
EclipseなどのIDEには、SQLの編集をサポートする機能が備わっています。もし、プログラム開発にIDEを活用しているのなら、SQLの構文チェックにも活用してください。
プリペアドステートメントを利用する
もし、SQLをプログラムで合成している場合、実際にプログラムを実行してみないと、どのようなSQLが使われているか解らない、という問題があります。
このようなケースでは、SQLに構文エラーがあったとしても、その原因を調べるのは大変です。それなら、プリペアドステートメントを利用されてはいかがでしょうか。
プリペアドステートメントとは、プログラム側の変数で置き換える箇所を「?」などで置き換えたSQLを用意し、その値を別のコマンドで指定する方法です。
そして、この方法なら、事前にSQLの構文チェックができるので、エラーを減らすことが可能です。
PHPによるプリペアドステートメントの例 // DB接続およびプリペアドステートメント $dbh = new PDO('mysql:host=localhost;dbname=test', $user. $passwd); $stmt = $dbh->prepare("INSERT INTO registry (name, value) VALUES (?, ?)"); $stmt->bindParam(1, $name); $stmt->bindParam(2, $value); // 行を挿入します $name = 'one'; $value = 1; $stmt->execute();
プリペアドステートメントは、多くのプログラム言語で利用できます。興味のある方は、下記のサイトを参照してください。
PreparedStatement (Java Platform SE 8)
プリペアドステートメントおよびストアドプロシージャ
まとめ
これまで説明したように、SQLで構文エラーが発生すると、どこが間違っているか探すのが面倒です。プログラムと同じ編集支援ツールなどを使い、構文エラーそのものを減らしましょう。
また、プログラムから利用する場合、SQLの合成方法によっては、そのデバックが面倒なケースもあります。事前に検証しやすいプリペアドステートメントの利用を検討してください。