7
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GitHub CopilotとT-SQL Analyzer(MCP Server)を連携してSQLをレビューしてもらう

Last updated at Posted at 2025-12-08

はじめに

自分の書いたSQLがベストプラクティスに沿っているかをチェックしたいときにどうしますか?

今回紹介する T-SQL Analyzer は、140以上のルールで SQL Serverの T-SQL のアンチパターンや設計上の問題を検出してくれる無料のコマンドラインツールです。さらに VS Code の MCP サーバー として設定すれば、GitHub Copilot が SQL ファイルを自動で分析してくれるようになります。

この記事では、環境構築から実際の使い方までを解説します。

T-SQL Analyzer とは

Microsoft と SQL Server コミュニティが作成したCLIツールです。 140以上のルール を元に、以下のような問題を検出します。

  • パフォーマンスの問題
  • 設計上の問題(命名規則違反など)
  • アンチパターン

詳細は公式ブログを参照してください。
https://devblogs.microsoft.com/azure-sql/sql-analysis-dotnet-tool/

普通の LLM によるレビューとの違い

「Gemini や Claude に直接 SQL をレビューしてもらうのと何が違うの?」という疑問があると思います。

観点 普通の LLM レビュー T-SQL Analyzer + Copilot
ルールの一貫性 プロンプトや文脈で結果がブレる 140以上の固定ルールで常に一貫した結果
検出の網羅性 見落としがある場合もある 体系的にすべてのルールをチェック
根拠の明確さ 「一般的に〜」という曖昧な説明 ルール ID(例:SRD0005)で明確に特定
CI/CD 統合 難しい コマンドラインツールなので容易
オフライン実行 不可 可能

T-SQL Analyzer で体系的に問題を検出Copilot がわかりやすく説明・修正提案 という組み合わせが強力です。

環境構築

M1 Macを例に構築手順を記載します。

Step 1: .NET SDK のインストール

T-SQL Analyzer は .NET 8 ツールなので、まず SDK が必要です。
今回は .NET 10をインストールしました。

1.公式サイトから macOS Arm64 版をダウンロード
https://dotnet.microsoft.com/ja-jp/download/dotnet/8.0

2..pkg ファイルを実行してインストール

3.シンボリックリンクを作成

.pkg インストール後も dotnet コマンドが見つからない場合はシンボリックリンク作成で解決します。

sudo ln -s /usr/local/share/dotnet/dotnet /usr/local/bin/

4.動作確認

dotnet --version
# 8.0.xxx 以上であれば OK

Step 2: T-SQL Analyzer のインストール

dotnet tool install --global ErikEJ.DacFX.TSQLAnalyzer.Cli

動作確認

tsqlanalyze --help

以下のように表示されれば成功です:

                 _____           ____     ___    _            _                      _                      
                |_   _|         / ___|   / _ \  | |          / \     _ __     __ _  | |  _   _   ____   ___ 
                  | |    _____  \___ \  | | | | | |         / _ \   | '_ \   / _` | | | | | | | |_  /  / _ \
                  | |   |_____|  ___) | | |_| | | |___     / ___ \  | | | | | (_| | | | | |_| |  / /  |  __/
                  |_|           |____/   \__\_\ |_____|   /_/   \_\ |_| |_|  \__,_| |_|  \__, | /___|  \___|
                                                                                         |___/              
T-SQL Analyzer CLI 1.0.35

Step 3: VS Code MCP サーバーの設定

ブラウザで以下のリンクを開くと、VS Code が起動して MCP サーバーの設定を促されます:

vscode:mcp/install?%7B%22name%22%3A%22tsqlanalyzer%22%2C%22command%22%3A%22tsqlanalyze%22%2C%22args%22%3A%5B%22-mcp%22%5D%7D

または、手動で ~/Library/Application Support/Code/User/mcp.json を編集してください。

{
	"servers": {
		"tsqlanalyzer": {
			"command": "tsqlanalyze",
			"args": [
				"-mcp"
			],
			"type": "stdio"
		}
	},
	"inputs": []
}

設定後、VS Code を再起動してください。

使ってみる

サンプル:問題だらけの SQL

以下のような アンチパターンを踏みまくったSQL を用意しました。

test.sql
SELECT * FROM Users, Orders 
WHERE Users.id = Orders.user_id 
  AND YEAR(Orders.order_date) = 2024
  AND Users.name LIKE '%hoge%'
  AND Orders.amount > '5000'
  OR Users.status = 1;

コマンドラインで分析

SQL ファイルがあるフォルダで実行
配下のSQLファイルを全て分析してれるはず....

tsqlanalyze

と思いきや、.sqlファイルがあるにも関わらず分析してくれません。

Analyzed 1 files in 3.969 seconds using 'Microsoft.Rules.Data, Smells, SqlServer.Rules'. 0 problems found.

確認したところ、T-SQL Analyzer はCREATE文のみが対象のようです。
適当なビューのCREATE文にします。

test_create.sql
IF OBJECT_ID(N'dbo.vw_TestUsersOrders', N'V') IS NOT NULL
    DROP VIEW dbo.vw_TestUsersOrders;
GO
CREATE VIEW dbo.vw_TestUsersOrders
AS
SELECT * FROM Users, Orders 
WHERE Users.id = Orders.user_id 
  AND YEAR(Orders.order_date) = 2024
  AND Users.name LIKE '%hoge%'
  AND Orders.amount > '5000'
  OR Users.status = 1;
GO

無事、分析してくれました。
image.png

実際にはGitでSQLを管理する際は、CREATE TABLECREATE PROCEDUREなどで管理されることが多いと思うのであまり問題にならないと思います。

GitHub Copilot で分析

これをGithub Copilotと連携してみます。

  1. VS Code で SQL ファイルを開く
  2. GitHub Copilot Chat を Agent モード で開く
  3. 「この SQL ファイルを分析して」と依頼

Copilot が T-SQL Analyzer を呼び出し、以下のような分析結果を返してくれます:

このSQLファイルには以下の問題があります:

主な問題点

  1. SELECT * の使用

    • 必要な列のみを明示的に指定すべきです
    • パフォーマンスとメンテナンス性の観点から推奨されません
  2. 暗黙的なJOIN構文

    • FROM Users, Orders WHERE... ではなく、明示的な INNER JOIN を使用すべきです
    • 可読性が低く、条件の意図が不明確になります
  3. 関数を列に適用(SARGable違反)

    • YEAR(Orders.order_date) = 2024 はインデックスを使用できません
    • Orders.order_date >= '2024-01-01' AND Orders.order_date < '2025-01-01' のように書き換えるべきです
  4. 前方一致・中間一致のLIKE検索

    • Users.name LIKE '%hoge%' は両端にワイルドカードがあるため、インデックスを使用できません
  5. 型の不一致

    • Orders.amount > '5000' で数値と文字列を比較しています
    • 暗黙的な型変換が発生し、パフォーマンスに影響します
  6. AND/OR演算子の優先順位の問題

    • OR 演算子が最後にあり、意図しない結果を返す可能性があります
    • 括弧で明示的にグループ化すべきです

以下のれすぽんすから、MCPサーバーを利用していることがわかります。
また、生のSQLを渡した場合でも、CREATE PROCEDURE文にラップしてレビューしてレビューしてくれました。気が利きますね。
image.png
image.png

Copilotがクエリも修正してくれました。

修正後の SQL

test.sql
SELECT
  u.id,
  u.name,
  u.status,
  o.id AS order_id,
  o.order_date,
  o.amount
FROM dbo.Users AS u
JOIN dbo.Orders AS o
  ON u.id = o.user_id
WHERE
  o.order_date >= '2024-01-01'
  AND o.order_date <  '2025-01-01'
  AND u.name LIKE '%hoge%'          -- SRP0002的には前方%を避けるのが望ましい
  AND o.amount > 5000               -- 文字列ではなく数値で比較
  AND (
    u.status = 1                    -- ORの優先順位は括弧で明示
  );

検出される問題の一覧

T-SQL Analyzer は 140以上のルールを持っています。主なカテゴリは以下の通りです。

カテゴリ
パフォーマンス Non-SARGable クエリ、SELECT *、暗黙的な型変換
設計 命名規則違反、主キーの欠如
セキュリティ SQL インジェクションのリスク
可読性 古い JOIN 構文、括弧の不足

全ルール一覧
https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/readme.md

高度な使い方

特定ルールを無視

ルールIDを指定して、特定ルールを除外できるようです。
例えば以下のルールは致し方ない場合もあるので除外してみましょう。

LIKEの前方ワイルドカード: '%hoge%'は非SARGable(SRP0002)。

MCPサーバーとして動かす場合は、mcp.jsonを以下のように修正します

{
	"servers": {
		"tsqlanalyzer": {
			"command": "tsqlanalyze",
			"args": [
				"-mcp",
				"-r",
				"Rules:-SqlServer.Rules.SRP0002;"
			],
			"type": "stdio"
		}
	},
	"inputs": []
}


しかし、上記のように-rオプションを追加したところMCPサーバーが起動エラーになってしまいました。

また、CLIから除外ルールを指定して実行してもうまく除外されませんでした。(SR0005が指摘に含まれてしまう)
このあたりはこれからのアップデートに期待したいです。

% tsqlanalyze -i ./test.sql -r "Rules:-SqlServer.Rules.SRD0005"                         
                                                                     _____           ____     ___    _            _                      _                      
                                                                    |_   _|         / ___|   / _ \  | |          / \     _ __     __ _  | |  _   _   ____   ___ 
                                                                      | |    _____  \___ \  | | | | | |         / _ \   | '_ \   / _` | | | | | | | |_  /  / _ \
                                                                      | |   |_____|  ___) | | |_| | | |___     / ___ \  | | | | | (_| | | | | |_| |  / /  |  __/
                                                                      |_|           |____/   \__\_\ |_____|   /_/   \_\ |_| |_|  \__,_| |_|  \__, | /___|  \___|
                                                                                                                                             |___/              
T-SQL Analyzer CLI 1.0.35
https://github.com/ErikEJ/SqlServer.Rules

warning: ./test.sql(9,17): Smells.SML002 : Best practice is to use two part naming. (https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/CodeSmells/SML002.md)
warning: ./test.sql(9,24): Smells.SML002 : Best practice is to use two part naming. (https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/CodeSmells/SML002.md)
warning: ./test.sql(9,10): Smells.SML005 : Avoid use of 'Select *'. (https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/CodeSmells/SML005.md)
warning: ./test.sql(9,10): Microsoft.Rules.Data.SR0001 : SELECT * ステートメントによって生成される結果セットの形状は、基になるテーブルやビューの構造が変更されると変わります。 
(https://learn.microsoft.com/sql/tools/sql-database-projects/concepts/sql-code-analysis/t-sql-design-issues#sr0001-avoid-select--in-stored-procedures-views-and-table-valued-functions)
warning: ./test.sql(12,25): Microsoft.Rules.Data.SR0005 : LIKE 述語では "%" で始まるパターンの使用は避けてください 
(https://learn.microsoft.com/sql/tools/sql-database-projects/concepts/sql-code-analysis/t-sql-performance-issues#sr0005-avoid-using-patterns-that-start-with--in-like-predicates)
warning: ./test.sql(9,24): Microsoft.Rules.Data.SR0010 : 旧スタイルの JOIN 構文が使用されています。 
(https://learn.microsoft.com/sql/tools/sql-database-projects/concepts/sql-code-analysis/t-sql-design-issues#sr0010-avoid-using-deprecated-syntax-when-you-join-tables-or-views)
warning: ./test.sql(9,10): SqlServer.Rules.SRD0006 : Avoid using SELECT *. (https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0006.md)
warning: ./test.sql(9,17): SqlServer.Rules.SRD0038 : Consider aliasing all table sources in the query. (https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0038.md)
warning: ./test.sql(9,24): SqlServer.Rules.SRD0038 : Consider aliasing all table sources in the query. (https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0038.md)
warning: ./test.sql(9,17): SqlServer.Rules.SRD0039 : Use fully qualified object names in SELECT, UPDATE, DELETE, MERGE and EXECUTE statements. [schema].[name]. 
(https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0039.md)
warning: ./test.sql(9,24): SqlServer.Rules.SRD0039 : Use fully qualified object names in SELECT, UPDATE, DELETE, MERGE and EXECUTE statements. [schema].[name]. 
(https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0039.md)
warning: ./test.sql(4,1): SqlServer.Rules.SRD0068 : Query statements should finish with a semicolon - ';'. (https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Design/SRD0068.md)
warning: ./test.sql(12,9): SqlServer.Rules.SRP0002 : Try to avoid using patterns that start with '%' when using the LIKE keyword if possible.  (Sargable) 
(https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Performance/SRP0002.md)
warning: ./test.sql(11,9): SqlServer.Rules.SRP0009 : Avoid wrapping columns within a function in the WHERE clause. (Sargable) (https://github.com/ErikEJ/SqlServer.Rules/blob/master/docs/Performance/SRP0009.md)

Analyzed 1 files in 1.396 seconds using 'Microsoft.Rules.Data, Smells, SqlServer.Rules'. 14 problems found.

SQL のフォーマット

フォーマットにも使えそうです。

tsqlanalyze -i ./query.sql -f

before

SELECT * FROM Users, Orders 
WHERE Users.id = Orders.user_id 
  AND YEAR(Orders.order_date) = 2024
  AND Users.name LIKE '%hoge%'
  AND Orders.amount > '5000'
  OR Users.status = 1;

after

SELECT *
FROM   Users, Orders
WHERE  Users.id = Orders.user_id
       AND YEAR(Orders.order_date) = 2024
       AND Users.name LIKE '%hoge%'
       AND Orders.amount > '5000'
       OR Users.status = 1;

細かく設定できそうなので、決まった形式にフォーマットを統一したい場合に便利かもしれません。
https://github.com/madskristensen/SqlFormatter?tab=readme-ov-file#editorconfig-support

CI/CD への組み込み

コマンドラインツールなので、dotnetが動く環境であればどこでも動きます。
以下のようにGitHub Actions などに簡単に組み込めそうです。

- name: Analyze SQL
  run: |
    dotnet tool install --global ErikEJ.DacFX.TSQLAnalyzer.Cli
    tsqlanalyze -i ./sql/ --output xml > analysis-result.xml

まとめ

T-SQL Analyzer + VS Code MCP サーバーの組み合わせにより以下が実現できそうです。

  • 一貫したルール で SQL をチェック
  • GitHub Copilot がわかりやすく説明・修正提案
  • CI/CD に組み込んで自動チェック

SQL Server を使っている方は、ぜひ導入してみてください。

参考リンク

7
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?