クエリ ビルダーで作られたクエリを実行すると構文エラーが発生する

福原 宗稚
SQL Developer Support Engineer

 

Visual Studio 2008、 Visual Studio 2010のクエリビルダーで、珍しい現象ではありますが、遭遇してしまうと不便だと思われる現象がありましたので、ご紹介します。

クエリ ビルダーとは

まず、クエリ ビルダーとは、SQL Server 等データベースへのクエリを GUI を使って定義できる便利なツールです。(Visual Studio で一例としては、データセット デザイナーでTableAdapter 構成ウィザードを使用する際に使用されます。)

TableAdapter 構成ウィザードでは、「SQL ステートメントの入力」画面から、「クエリ ビルダー」ボタンをクリックすることで、「クエリ ビルダー」画面が起動します。ここで、結合するテーブルを追加したり、列を追加したり、絞り込み条件を追加するという操作を GUI で操作することができます。

 

現象

「SQL ステートメントの入力」画面でクエリを記述した後、追加で修正等行う際、クエリ ビルダーを使用することがあります。

クエリ ビルダーの動作の一つとして、必ずしも必要ではない、列名につけている [ ] や “ “ を削除し、クエリを整形するという操作があります。下図のクエリは SQL Server 2008 や SQL Server 2008 R2 に接続している場合、通常 [ ] がなくても正常にクエリが実行できます。そのため、「SQL ステートメントの入力」画面で列名につけている [ ] は、クエリ ビルダーを開いたタイミングで削除されます。[ ] が削除されたクエリを実行する際に、SQL Server 側の設定によって、エラーとなる場合があります。

image

    • 通常の場合

      「クエリの実行」をクリックすると、正常に結果が返ってきます。

 

    • エラーになる場合

      「クエリの実行」をクリックすると、列名に含まれる中点 「・」 (もしくは中黒とも言います) に関して、構文エラー「Incorrect syntax near ‘・’.」が発生する場合があります。

      image

原因

クエリを実行しているデータベースの互換性レベルが 80 (SQL Server 2000 相当) の場合にエラーが発生します。

列名に使用できる文字はデータベース識別子として定義されており、SQL Server 2000 と SQL Server 2005 以降で大きな違いがあります。

  • SQL Server 2000 :
    Unicode 規格 2.0 に含まれる文字が使用可能であり、中点はまだ識別子として使用することができない。
    中点を含む列名(例えば、「部門・グループコード」) は、[ ] や " " で囲まない場合には、構文エラーが発生する。
  • SQL Server 2005 以降のバージョン :
    Unicode 規格 3.2 に含まれる文字が使用可能であり、中点も識別子として使用することが可能である。
    中点を含む列名(例えば、「部門・グループコード」) は、[ ] や " " で囲まなくても正常に実行できる。

 
列名に使用できる文字は、データベースの互換性レベルに応じて判断されるため、SQL Server 2008 R2 だったとしても、
互換性レベル 80 (SQL Server 2000 の互換性レベル) に設定されたデータベースであれば、上記の「SQL Server 2000」の場合と同様の動作となります。

クエリ ビルダーでは、データベースの互換性レベルまでは判断していないため、対象のデータベースが互換性レベル 80 でも [ ] は不要と判断し、[ ] を削除します。その結果、構文エラーが発生します。

対処方法

下記のいずれかで対処できます。

  1. クエリ ビルダーを使用しない
  2. 互換性レベルを 90 (SQL Server 2005) 以上に設定する

1. クエリ ビルダーを使用しない

せっかくの便利なツールを使用しないというのは残念ですが、クエリ ビルダーを使用せず、「SQL ステートメントの入力」画面ですべてクエリを記述することで回避できます。

2. 互換性レベルを 90 (SQL Server 2005) 以上に設定する

こちらはやや長期的な検討が必要な対処方法となります。

互換性レベルは、以前のバージョンとの互換性を設定できるため、以前のバージョンからデータベースを移行された場合には、よく使用される機能かと思います。しかしながら、あくまでも移行時の暫定的な手段として用意している機能のため、長期的には使用されている SQL Server のバージョンと同じ互換性レベルを使用するよう検証を実施いただくことを推奨します。 (参考 : ALTER DATABASE 互換性レベル (Transact-SQL) )