Início rápido: Ligar-se e fazer consultas com o Microsoft.Data.SqlClient

Neste quickstart, constróis uma aplicação de consola .NET com a Microsoft.Data.SqlClient 7.1.1.

Começas com uma pasta vazia, o SDK .NET e uma base de dados SQL Server ou SQL do Azure à qual podes aceder a partir do teu computador. Terminas com uma aplicação de consola que cria uma tabela, insere duas linhas com parâmetros e lê-as de volta.

Ao longo do caminho, a aplicação:

  • Lê a sua cadeia de ligação a partir de uma variável de ambiente em vez do código-fonte.
  • Abre uma ligação de forma assíncrona.
  • Utiliza parâmetros para cada valor que envia para a base de dados.
  • Trata de erros SQL e cancelamento.

Para integrar o mesmo acesso a dados numa API web, consulte Quickstart: Use Microsoft. Data.SqlClient numa aplicação ASP.NET Core. Usa a mesma tabela.

Pré-requisitos

  • O .NET SDK 10 ou um .NET SDK posterior suportado. O SDK corre no Windows, Linux e macOS. O SDK também constrói a versão .NET Framework do exemplo, que funciona apenas no Windows e necessita do .NET Framework 4.8.1. Utilize a versão .NET para novos desenvolvimentos.
  • Um editor de código. Pode usar o Visual Studio, Visual Studio Code ou qualquer editor juntamente com a linha de comando .NET. Este artigo utiliza a CLI .NET.
  • Uma base de dados à qual te possas ligar. Se não tiveres um, cria um usando as seguintes opções.

Criar um banco de dados SQL

Criar ou ligar-se a uma base de dados SQL numa das seguintes plataformas:

Permissões de banco de dados

A aplicação cria a sua própria tabela, por isso não precisa de dados de exemplo. A identidade da base de dados precisa de permissão para se ligar e criar, inserir e selecionar de uma tabela.

Para base de dados SQL no Microsoft Fabric, copie os nomes do servidor e da base de dados a partir do item da base de dados SQL. Não utilizes o endpoint de análise de SQL. A identidade precisa da permissão de leitura do item, que pode ser concedida por uma função do espaço de trabalho ou por uma permissão do item. Para mais informações, veja Autenticação na base de dados SQL. A autenticação SQL não é suportada.

Para o Base de Dados SQL do Azure, configure a autenticação do Microsoft Entra ID e o acesso à base de dados.

Criar o projeto

Numa pasta vazia, execute estes comandos:

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

O pacote de extensão fornece os modos de autenticação Microsoft Entra do driver, como Active Directory Default. Se a sua aplicação usar apenas autenticação SQL ou autenticação integrada no Windows, pode omitir Microsoft.Data.SqlClient.Extensions.Azure. Quando usares ambos os pacotes, mantém as versões iguais. Para outras opções de instalação, veja Instalar, atualizar e distribuir Microsoft.Data.SqlClient.

Configurar a ligação

Define a SQL_CONNECTION_STRING variável ambiente para a tua base de dados. Não inclua uma palavra-passe, um token de acesso nem uma cadeia de ligação de produção no código-fonte.

Escolhe um destes pontos de partida e substitui os marcadores de lugar.

SQL do Azure ou base de dados SQL em Fabric com Microsoft Entra ID

Inicie sessão com uma identidade Microsoft Entra que tenha acesso à base de dados. Para desenvolvimento local, utilize uma ferramenta de desenvolvimento como a CLI do Azure:

az login

Copie o nome exato do servidor e da base de dados da base de dados SQL do Azure ou do item da base de dados SQL no Fabric. Para o PowerShell:

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

Para Bash:

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

Para uma aplicação alojada no Azure, conceda à identidade gerida acesso à base de dados e depois use Authentication=Active Directory Managed Identity. Para outras opções, veja autenticação Microsoft Entra com Microsoft. Data.SqlClient.

SQL Server com autenticação SQL

Usa o servidor, porta, base de dados e login para a tua instância do SQL Server. O exemplo seguinte é para uma instância de desenvolvimento local que não tem um certificado fidedigno. Para o PowerShell:

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

Para 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 ignora a validação do certificado do servidor. Use-a apenas com uma instância de desenvolvimento local que não tenha um certificado fidedigno. Para instâncias partilhadas ou de produção de SQL Server, instale um certificado em que o cliente confia, use o nome do servidor nesse certificado e remova TrustServerCertificate=true. Para obter mais informações, consulte Criptografia e validação de certificado em Microsoft.Data.SqlClient.

Se o seu ambiente suportar autenticação integrada no Windows ou Kerberos, substitua User ID e Password por Integrated Security=true. Para requisitos de configuração, consulte SQL Server e autenticação do Windows.

Adicionar o código

Substitua o conteúdo de Program.cs por este código:

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;
}

Executar o aplicativo

Execute o aplicativo:

dotnet run

Na primeira vez que executas a aplicação, a tabela está vazia e o resultado é o seguinte:

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)

As vossas marcas temporais são diferentes. Cada corrida posterior acrescenta mais duas linhas, de modo que os IDs continuam a partir da última corrida.

Se a aplicação não conseguir ligar, imprime o número de erro SQL, o ID da ligação do cliente, a mensagem de erro e a mensagem de exceção interna, e depois sai com o código 3. Para erros comuns, veja Resolução de Problemas.

Como funciona o código

  • OpenAsync, ExecuteNonQueryAsync, ExecuteScalarAsync, ExecuteReaderAsync e ReadAsync recebem o mesmo CancellationToken. Pressione Ctrl+C para cancelar o trabalho em progresso.
  • O comando insert é criado uma vez e executado uma vez para cada mensagem. Apenas o valor do parâmetro muda.
  • Os tipos e tamanhos dos parâmetros correspondem às colunas da tabela. Os parâmetros enviam valores separadamente do texto SQL, o que impede que esses valores alterem o comando e ajuda o SQL Server a reutilizar planos de consulta.
  • OUTPUT INSERTED.Id retorna o novo valor de identidade, pelo que ExecuteScalarAsync retorna assim o ID sem uma segunda consulta.
  • await using liberta os comandos, o leitor e a ligação, mesmo quando ocorre uma exceção. Libertar a ligação devolve-a ao pool de ligações. A versão do .NET Framework usa blocos using, porque estes tipos não implementam IAsyncDisposable no .NET Framework.
  • SqlException.Number identifica o erro e ClientConnectionId permite associar uma falha do cliente aos registos do lado do servidor. Para falhas de ligação no Linux e macOS, a causa está frequentemente apenas em InnerException, como uma falha de validação de certificado por detrás da mensagem genérica error: 35 - An internal exception was caught.

Troubleshoot

Erro ou sintoma O que deve verificar Mais informações
The certificate chain was issued by an authority that is not trustedno Windows. No Linux e macOS, error: 35 - An internal exception was caught, seguido da exceção interna Certificate failed chain validation com UntrustedRoot. O cliente não confia no certificado do servidor, ou o nome do servidor na cadeia de ligação não corresponde ao certificado. Instale um certificado de confiança. Utilize TrustServerCertificate=true apenas com uma instância de desenvolvimento local. Encriptação e validação de certificados na Microsoft. Data.SqlClient
SQL error 18456 com Login failed for user O nome de utilizador, palavra-passe ou nome da base de dados está errado, ou o login não tem acesso à base de dados. Para o Microsoft Entra ID, verifique se a identidade foi adicionada como utilizador da base de dados. Guia de resolução de problemas do SqlClient
A network-related or instance-specific error occurred com error: 26, error: 40, ou The wait operation timed out. No Linux e macOS, um timeout mostra SQL error 258 com error: 35, seguido da exceção interna The connection attempt timed out. O nome do servidor ou porta está errado, o servidor não aceita ligações TCP remotas, ou um firewall bloqueia a porta. Para SQL do Azure, verifique as regras do firewall do servidor. Guia de resolução de problemas do SqlClient
System.ArgumentException: Cannot find an authentication provider for 'ActiveDirectoryDefault' A cadeia de ligação usa um modo de autenticação Active Directory, mas o projeto não faz referência a Microsoft.Data.SqlClient.Extensions.Azure. Adicione o pacote com a mesma versão como Microsoft.Data.SqlClient. A autenticação Microsoft Entra passa para um pacote de extensão na 7.0
CS0234: The type or namespace name 'Data' does not exist in the namespace 'Microsoft' O projeto não faz referência ao Microsoft.Data.SqlClient pacote. Execute o dotnet add package comando a partir da pasta que contém o ficheiro do projeto. Instalar, atualizar e implementar a Microsoft. Data.SqlClient
Restaurar relatórios NU1902 ou NU1903 para um pacote transitivo Um pacote do qual o controlador depende tem um aviso de segurança publicado. Ações quando pacotes com vulnerabilidades conhecidas são reportados

Limpeza de recursos

A tabela fica na tua base de dados depois de a aplicação ser fechada. Se não planeias continuar com o quickstart do ASP.NET Core, que usa a mesma tabela, elimina-a com qualquer ferramenta de consulta:

DROP TABLE IF EXISTS dbo.SqlClientQuickstart;

Depois apaga a pasta do projeto. Na pasta-mãe, no PowerShell:

Remove-Item -Recurse -Force SqlClientQuickstart

Para Bash:

rm -rf SqlClientQuickstart

Limpa a variável de ambiente para que a cadeia de ligação não fique na tua sessão shell. Para PowerShell, execute Remove-Item Env:\SQL_CONNECTION_STRING. No Bash, execute unset SQL_CONNECTION_STRING.

Use o padrão numa aplicação

Mantenha estes limites quando mover a amostra para uma API, serviço, aplicação de ambiente de trabalho ou trabalhador em segundo plano:

  • Carregue a informação de ligação através do sistema de configuração da aplicação.
  • Abra uma conexão para uma breve unidade de trabalho e, em seguida, elimine-a.
  • Passe um CancellationToken através das chamadas open, command e reader.
  • Defina os tempos de espera dos comandos com base na operação.
  • Use parâmetros para cada valor que venha de fora da instrução SQL.
  • Faça login SqlException.Number e ClientConnectionId sem credenciais de registo ou tokens de acesso.
  • Adicione novas tentativas apenas para falhas transitórias e só quando repetir a operação for seguro.

Passos seguintes