クイックスタート: Microsoft.Data.SqlClient で接続してクエリを実行する

このクイックスタートでは、Microsoft.Data.SqlClient 7.1.1 を使って .NET コンソール アプリを構築します。

まずは空のフォルダ、.NET SDK、そしてパソコンからアクセス可能なSQL ServerやAzure SQLデータベースから始めます。 最後にコンソールアプリでテーブルを作成し、パラメータを指定して2行挿入し、それを読み返します。

その過程で、アプリは次のことを行います:

  • ソースコードではなく環境変数から接続文字列を読み取る。
  • 非同期で接続を開きます。
  • データベースに送るすべての値に対してパラメータを使用します。
  • SQLエラーやキャンセルを処理します。

同じデータ アクセスを Web API に組み込むには、「Quickstart: ASP.NET Core アプリで Microsoft.Data.SqlClient を使用する」をご覧ください。 同じテーブルを使っています。

前提条件

  • .NET 10 SDKまたはそれ以降でサポートされている .NET SDKです。 SDKはWindows、Linux、macOSで動作します。 SDKはサンプルの.NET Framework版も構築しており、これはWindowsでのみ動作し、.NET Framework 4.8.1が必要です。 新しい開発には.NET版を使いましょう。
  • コードエディタ。 Visual Studio、Visual Studio Code、または他のエディタと.NET CLIを組み合わせて使用できます。 この記事は.NET CLIを使用しています。
  • 接続できるデータベースです。 もし持っていなければ、以下のオプションを使って作成してください。

SQL データベースを作成する

以下のいずれかのプラットフォームでSQLデータベースを作成または接続してください:

データベース権限

アプリは独自のテーブルを作成するので、サンプルデータは不要です。 データベースのアイデンティティは接続やテーブルの作成、挿入、選択の許可が必要です。

Microsoft FabricのSQLデータベースでは、SQLデータベースの項目からサーバー名とデータベース名をコピーします。 SQLアナリティクスエンドポイントは使わないでください。 アイデンティティには「アイテムを読み込み」権限が必要で、ワークスペースロールやアイテム権限で提供できます。 詳細については、 SQLデータベースにおける認証をご覧ください。 SQL認証はサポートされていません。

Azure SQL Databaseでは、Microsoft Entra IDの認証とデータベースアクセスを設定してください。

プロジェクトを作成する

空のフォルダで、以下のコマンドを実行してください:

dotnet new console --framework net10.0 --name SqlClientQuickstart
cd SqlClientQuickstart
dotnet add package Microsoft.Data.SqlClient --version 7.1.1
dotnet add package Microsoft.Data.SqlClient.Extensions.Azure --version 7.1.1

拡張パッケージは、Active Directory DefaultなどのドライバーのMicrosoft Entra認証モードを提供します。 もしアプリがSQL認証のみを使用しているか、統合認証Windows使っている場合は、Microsoft.Data.SqlClient.Extensions.Azureを省略しても構いません。 両方のパッケージを使う場合は、それぞれのバージョンを同じにしてください。 その他のインストール オプションについては、「Microsoft.Data.SqlClient のインストール、更新、デプロイ」をご覧ください。

接続の設定

データベースの SQL_CONNECTION_STRING 環境変数を設定してください。 ソースコードにパスワード、アクセストークン、または本番環境の接続文字列を入れないでください。

これらの開始点から1つを選び、プレースホルダーを置き換えてください。

Azure SQL または Microsoft Entra ID を使用した Fabric 内の SQL データベース

データベースにアクセスできるMicrosoft EntraのIDでサインインしてください。 ローカル開発の場合は、Azure CLIのような開発者ツールをご利用ください。

az login

Azure SQLデータベースまたはFabricのSQLデータベース項目から正確なサーバー名とデータベース名をコピーしてください。 PowerShell の場合:

$env:SQL_CONNECTION_STRING = 'Server=tcp:<server>,1433;Database=<database>;Authentication=Active Directory Default;Encrypt=Strict;MultiSubnetFailover=true;Connect Timeout=30'

Bash の場合:

export SQL_CONNECTION_STRING='Server=tcp:<server>,1433;Database=<database>;Authentication=Active Directory Default;Encrypt=Strict;MultiSubnetFailover=true;Connect Timeout=30'

Azure でホストされているアプリの場合、そのマネージド ID にデータベースへのアクセスを付与してから、Authentication=Active Directory Managed Identity を使いましょう。 その他のオプションについては、Microsoft.Data.SqlClient を使用した Microsoft Entra 認証を参照してください。

SQL認証付きSQL Server

SQL Serverインスタンスのサーバー、ポート、データベース、ログインを使いましょう。 以下の例は、信頼できる証明書を持っていないローカル開発インスタンスのものです。 PowerShell の場合:

$env:SQL_CONNECTION_STRING = 'Server=tcp:<server>,1433;Database=<database>;User ID=<user-id>;Password=<password>;Encrypt=true;TrustServerCertificate=true;Connect Timeout=30'

Bash の場合:

export SQL_CONNECTION_STRING='Server=tcp:<server>,1433;Database=<database>;User ID=<user-id>;Password=<password>;Encrypt=true;TrustServerCertificate=true;Connect Timeout=30'

Caution

TrustServerCertificate=true サーバー証明書の検証を省略します。 信頼できる証明書がないローカル開発インスタンスでのみ使ってください。 共有または本番SQL Serverインスタンスの場合、クライアントが信頼する証明書をインストールし、その証明書にサーバー名を使い、TrustServerCertificate=trueを削除してください。 詳細については、「 Microsoft.Data.SqlClient での暗号化と証明書の検証」を参照してください。

環境がWindows 統合認証または Kerberos に対応しているなら、User IDとPasswordをIntegrated Security=trueに置き換えてください。 セットアップ要件については、SQL ServerおよびWindows 認証を参照してください。

コードを追加する

Program.csの内容を次のコードに置き換えます。

using System.Data;
using Microsoft.Data.SqlClient;

string? connectionString =
    Environment.GetEnvironmentVariable("SQL_CONNECTION_STRING");

if (string.IsNullOrWhiteSpace(connectionString))
{
    Console.Error.WriteLine(
        "Set the SQL_CONNECTION_STRING environment variable.");
    return 1;
}

using var cancellation = new CancellationTokenSource();
Console.CancelKeyPress += (_, eventArgs) =>
{
    eventArgs.Cancel = true;
    cancellation.Cancel();
};

try
{
    await using var connection = new SqlConnection(connectionString);
    await connection.OpenAsync(cancellation.Token);

    const string createTableSql = """
        IF OBJECT_ID(N'dbo.SqlClientQuickstart', N'U') IS NULL
        BEGIN
            CREATE TABLE dbo.SqlClientQuickstart
            (
                Id int IDENTITY(1, 1) PRIMARY KEY,
                Message nvarchar(200) NOT NULL,
                CreatedAt datetimeoffset NOT NULL
                    CONSTRAINT DF_SqlClientQuickstart_CreatedAt
                    DEFAULT sysdatetimeoffset()
            );
        END;
        """;

    await using (var createCommand =
        new SqlCommand(createTableSql, connection) { CommandTimeout = 30 })
    {
        await createCommand.ExecuteNonQueryAsync(cancellation.Token);
    }

    const string insertSql = """
        INSERT INTO dbo.SqlClientQuickstart (Message)
        OUTPUT INSERTED.Id
        VALUES (@message);
        """;

    string[] messages =
    [
        "Hello from Microsoft.Data.SqlClient",
        "Parameters keep values out of the SQL text"
    ];

    int firstId = 0;
    await using (var insertCommand =
        new SqlCommand(insertSql, connection) { CommandTimeout = 30 })
    {
        SqlParameter messageParameter =
            insertCommand.Parameters.Add("@message", SqlDbType.NVarChar, 200);

        foreach (string message in messages)
        {
            messageParameter.Value = message;
            int id = (int)(await insertCommand.ExecuteScalarAsync(
                cancellation.Token))!;
            Console.WriteLine($"Inserted row {id}.");
            firstId = firstId == 0 ? id : firstId;
        }
    }

    const string querySql = """
        SELECT Id, Message, CreatedAt
        FROM dbo.SqlClientQuickstart
        WHERE Id >= @firstId
        ORDER BY Id;
        """;

    await using var queryCommand =
        new SqlCommand(querySql, connection) { CommandTimeout = 30 };
    queryCommand.Parameters.Add("@firstId", SqlDbType.Int).Value = firstId;

    await using SqlDataReader reader =
        await queryCommand.ExecuteReaderAsync(cancellation.Token);

    while (await reader.ReadAsync(cancellation.Token))
    {
        Console.WriteLine(
            $"{reader.GetInt32(0)}: {reader.GetString(1)} " +
            $"(created {reader.GetDateTimeOffset(2):u})");
    }

    return 0;
}
catch (OperationCanceledException)
{
    Console.Error.WriteLine("The operation was canceled.");
    return 2;
}
catch (SqlException ex)
{
    Console.Error.WriteLine(
        $"SQL error {ex.Number}, connection {ex.ClientConnectionId}: " +
        ex.Message);
    if (ex.InnerException is not null)
    {
        Console.Error.WriteLine(ex.InnerException.Message);
    }
    return 3;
}

アプリを実行する

次のようにアプリを実行します。

dotnet run

アプリを初めて実行したとき、テーブルは空で、出力は次のようになります:

Inserted row 1.
Inserted row 2.
1: Hello from Microsoft.Data.SqlClient (created 2026-10-20 20:56:10Z)
2: Parameters keep values out of the SQL text (created 2026-10-20 20:56:10Z)

タイムスタンプは異なります。 その後の実行ごとに2行追加されるため、IDは前回の実行から継続されます。

もしアプリが接続できない場合は、SQLエラー番号、クライアント接続ID、エラーメッセージ、内側の例外メッセージを印刷し、その後コード3で終了します。 よくあるエラーについては、 トラブルシューティングを参照してください。

コードのしくみ

  • OpenAsync、 ExecuteNonQueryAsync、 ExecuteScalarAsync、 ExecuteReaderAsync、 ReadAsync はすべて同じ CancellationTokenを受けます。 進行中の作業をキャンセルするにはCtrl+Cボタンを押します。
  • insertコマンドは1回作成され、各メッセージごとに1回実行されます。 パラメータ値だけが変わる。
  • パラメータの種類やサイズはテーブルの列と一致しています。 パラメータはSQLテキストとは別に値を送るため、これらの値がコマンドを変更するのを防ぎ、SQL Serverがクエリプランを再利用するのに役立ちます。
  • OUTPUT INSERTED.Id 新しいIDENTITY 値を返すため、ExecuteScalarAsync は2つ目のクエリなしでIDを返します。
  • await using 例外が発生した場合でも、コマンド、リーダー、および接続を破棄します。 接続を破棄すると接続プールに戻されます。 .NET Frameworkバージョンではusingブロックが使われます。なぜなら、これらのタイプは.NETフレームワーク上でIAsyncDisposableを実装していないからです。
  • SqlException.Number エラーを特定し、 ClientConnectionId クライアントの失敗をサーバー側のログと照合できます。 LinuxやmacOSでの接続障害の原因は、多くの場合、一般的なInnerExceptionの背後にある証明書検証の失敗など、error: 35 - An internal exception was caughtに限られます。

Troubleshoot

エラーまたは症状 確認すべきこと 詳細情報
The certificate chain was issued by an authority that is not trusted を Windows で。 LinuxやmacOSでは、error: 35 - An internal exception was caughtに続いて、UntrustedRoot を伴う内部例外Certificate failed chain validationが表示されます。 サーバー証明書はクライアントに信頼されていなかったり、接続文字列のサーバー名が証明書と一致しないことがあります。 信頼できる証明書をインストールしてください。 TrustServerCertificate=trueはローカル開発インスタンスでのみ使用してください。 Microsoftにおける暗号化と証明書検証。Data.SqlClient
SQL error 18456 と Login failed for user ユーザー名、パスワード、またはデータベース名が間違っているか、ログインにそのデータベースへのアクセス権がありません。 Microsoft Entra IDについては、ID エンティティがデータベース ユーザーとして追加されているか確認してください。 SqlClient トラブルシューティング ガイド
A network-related or instance-specific error occurredでerror: 26、error: 40、またはThe wait operation timed out。 LinuxやmacOSでは、タイムアウトでSQL error 258 を伴う error: 35が表示され、その後に内部例外The connection attempt timed outが表示されます。 サーバー名やポートが間違っている、サーバーがリモートTCP接続を受け付けていない、あるいはファイアウォールがポートをブロックしている場合などです。 Azure SQLについては、サーバーのファイアウォールルールを確認してください。 SqlClient トラブルシューティング ガイド
System.ArgumentException: Cannot find an authentication provider for 'ActiveDirectoryDefault' 接続文字列はActive Directory認証モードを使用していますが、プロジェクトでは Microsoft.Data.SqlClient.Extensions.Azure を参照していません。 Microsoft.Data.SqlClientと同じバージョンのパッケージを追加してください。 Microsoft Entra認証は7.0で拡張パッケージに移行
CS0234: The type or namespace name 'Data' does not exist in the namespace 'Microsoft' プロジェクトは Microsoft.Data.SqlClient パッケージを参照していません。 プロジェクト ファイルを含むフォルダーで dotnet add package コマンドを実行します。 Microsoft.Data.SqlClient のインストール、更新、デプロイ
トランジティブ パッケージについて NU1902 または NU1903 の復元を報告します ドライバーが依存するパッケージには公開されたアドバイザリがあります。 既知の脆弱性を持つパッケージが報告された場合の対応

リソースをクリーンアップする

アプリ終了後もテーブルはデータベースに残ります。 同じテーブルを使うASP.NET Coreクイックスタートを続ける予定がない場合は、任意のクエリツールで削除してください。

DROP TABLE IF EXISTS dbo.SqlClientQuickstart;

その後、プロジェクトフォルダを削除してください。 親フォルダーから、PowerShell の場合:

Remove-Item -Recurse -Force SqlClientQuickstart

Bash の場合:

rm -rf SqlClientQuickstart

環境変数をクリアして、接続文字列がシェルセッションに残らないようにしてください。 PowerShellの場合は Remove-Item Env:\SQL_CONNECTION_STRING を実行してください。 Bash では unset SQL_CONNECTION_STRING を実行します。

アプリケーションでパターンを使う

サンプルをAPI、サービス、デスクトップアプリ、またはバックグラウンドワーカーに移行する際には、以下の境界を守ってください。

  • アプリの設定システムを通じて接続情報を読み込みます。
  • 短い作業単位のために 1 つの接続を開き、終わったら破棄します。
  • CancellationTokenをオープンコール、コマンドコール、リーダーコールに通します。
  • 操作に応じてコマンドのタイムアウトを設定してください。
  • SQL文の外部から来るすべての値にパラメータを使いましょう。
  • SqlException.Number と ClientConnectionId を記録し、ログイン情報やアクセストークンはログに記録しないでください。
  • 再試行は一時的な故障のみ、かつ操作が安全に再現できる場合にのみ追加します。

次のステップ