Resolver o problema do driver go-mssqldb

Este artigo apresenta soluções para erros comuns e problemas de conectividade com o go-mssqldb driver.

Comece pelas verificações mais simples

Antes de ativares o verbose logging ou alterares as definições do pool, segue a seguinte lista:

  1. Verifique a acessibilidade básica: nome do servidor, porta, regras do firewall e se o SQL Server ou SQL do Azure está a aceitar ligações.
  2. Verifique os dados de autenticação: nome do controlador, nome de utilizador, palavra-passe, formato de domínio ou configuração fedauth.
  3. Verifique as definições do TLS: encrypt, os caminhos dos certificados, hostnameincertificate, e se TrustServerCertificate é apropriado para o ambiente.
  4. Só depois de a configuração da ligação estar correta, investigue o esgotamento do pool, ligações expiradas, a lógica de nova tentativa e o diagnóstico de consultas lentas ou bloqueadas.

Utilize as primeiras secções deste artigo para falhas no estabelecimento da ligação. Use as secções posteriores apenas depois de as ligações terem sucesso pelo menos por vezes e depois falharem sob carga, após tempo de inatividade ou durante o failover.

Erros de ligação

As secções seguintes abordam mensagens de erro comuns relacionadas com ligações e as suas soluções.

Não é possível abrir a ligação TCP

Mensagem de erro: unable to open tcp connection with host 'localhost:1433': dial tcp 127.0.0.1:1433: connectex: No connection could be made because the target machine actively refused it.

Causas e soluções:

  • O SQL Server não está a correr. Inicia o serviço SQL Server.
  • O TCP/IP não está ativado. Abra o Gestor de Configuração do SQL Server e ative o TCP/IP nosProtocolos de Configuração > de Rede do SQL Server.
  • Porto errado. Verifique a porta no Gestor de Configuração do SQL Server ou use o SQL Server Browser para instâncias nomeadas.
  • Firewall a bloquear a porta. Adicione uma regra de entrada para a porta 1433 (ou para a sua porta configurada).

Falha de login para o utilizador

Mensagem de erro: mssql: login error: Login failed for user '<user>'.

Causas e soluções:

  • Nome de utilizador ou palavra-passe incorretos. Verifique as credenciais.
  • A autenticação do SQL Server está desativada. Ativar o SQL Server e o modo de autenticação Windows nas propriedades do servidor.
  • O login não existe. Crie um login no SQL Server.
  • O login não tem acesso à base de dados do destino. Conceda acesso à base de dados com CREATE USER.

Erros de validação de certificados

Mensagem de erro: TLS Handshake failed: x509: certificate signed by unknown authority

Causas e soluções:

  • O servidor utiliza um certificado auto-assinado. Forneça o caminho do certificado com o certificate parâmetro ou serverCertificate , ou defina TrustServerCertificate=true apenas para desenvolvimento.
  • O certificado de CA não está na loja de confiança do sistema. Adicione o certificado da CA ao arquivo de certificados fidedignos do sistema operativo ou especifique-o com o parâmetro certificate.
  • O nome do anfitrião não corresponde. Use hostnameincertificate para especificar o nome esperado no certificado.

Para mais informações, consulte Encriptação e certificados.

Expirou o tempo limite de ligação

Mensagem de erro: unable to open tcp connection with host '<server>:1433': dial tcp: i/o timeout

Causas e soluções:

  • Problemas de conectividade de rede. Verifique se consegue aceder ao servidor usando telnet <server> 1433 ou Test-NetConnection -ComputerName <server> -Port 1433.
  • Falha na resolução DNS. Verifica se o nome de host se resolve corretamente.
  • Aumente dial timeout ou connection timeout na cadeia de ligação.

Erros de autenticação

As secções seguintes abrangem mensagens de erro de autenticação.

Falhas na autenticação NTLM

Mensagem de erro: NTLM authentication failed

Causas e soluções:

  • Formato de domínio incorreto. Use DOMAIN\user no parâmetro user id. No formato URL, codifica a barra inversa como %5C.
  • Palavra-passe errada. Verifique a palavra-passe do domínio.

Falhas de autenticação Kerberos

Mensagem de erro: krb5: cannot resolve KDC for realm

Causas e soluções:

  • Faltava ou mal configurado /etc/krb5.conf. Verifique se a [realms] secção contém o endereço KDC correto para o seu domínio.
  • Sem bilhete válido. Corre klist para verificar se há um bilhete válido, ou corre kinit para obter um.
  • Ficheiro keytab não encontrado. Verifica o caminho no krb5-keytabfile parâmetro.

Para mais informações, consulte SQL Server e Windows authentication.

Falhas na autenticação do Microsoft Entra ID

Mensagem de erro: clientCredentialFromCert: error reading certificate: ... ou DefaultAzureCredential: failed to acquire a token

Causas e soluções:

  • ID de cliente, ID de locatário ou segredo de cliente incorreto. Verifique os valores na cadeia de ligação ou nas variáveis de ambiente.
  • A identidade gerida não está configurada no host. Verifique a identidade no portal Azure.
  • Falta a importação do pacote azuread. Importe github.com/microsoft/go-mssqldb/azuread e utilize o nome do controlador azuresql.

Para mais informações, consulte a autenticação do ID Microsoft Entra.

Falha de login para o utilizador '' (nome de utilizador vazio)

Mensagem de erro: mssql: login error: Login failed for user ''.

Causa: Usaste sql.Open("sqlserver", ...) com um fedauth parâmetro. A autenticação Entra ID requer o nome do azuresql condutor registado pela azuread encomenda. Com o driver padrão sqlserver , o fedauth parâmetro é ignorado e o driver tenta autenticação SQL sem nome de utilizador.

Solução: Importe o pacote azuread e utilize o nome do controlador azuresql:

import _ "github.com/microsoft/go-mssqldb/azuread"

db, err := sql.Open("azuresql",
    "sqlserver://<server>.database.windows.net?database=AdventureWorks2025&fedauth=ActiveDirectoryDefault&encrypt=true&TrustServerCertificate=false")
if err != nil {
    panic(err)
}

Para mais informações, consulte a autenticação do ID Microsoft Entra.

Erros de consulta

As secções seguintes abordam as mensagens de erro de execução da consulta.

LastInsertId não suportado

Mensagem de erro: LastInsertId is not supported. Please use the OUTPUT clause or add 'select ID = convert(bigint, SCOPE_IDENTITY())' to the end of your query.

Solução: O go-mssqldb driver não suporta LastInsertId(). Utilize uma cláusula OUTPUT ou uma consulta SCOPE_IDENTITY() em separado.

Tabela temporária não encontrada

Mensagem de erro: mssql: Invalid object name '#TempTable'.

Causa: As tabelas temporárias são específicas de cada conexão. Se criares uma tabela temporária numa chamada e a consultares noutra, podem usar ligações diferentes do pool.

Solução: Utilize db.Conn(ctx) para fixar a uma única ligação ou envolva as operações numa transação.

Para mais informações, consulte Procedimentos armazenados.

Erros do SQL do Azure

As secções seguintes abordam erros específicos do Base de Dados SQL do Azure.

Números de erro de ligação transitória

Use a lista partilhada seguinte como referência para erros transitórios de estabelecimento de ligação e falhas de transporte no percurso do pedido elegíveis para nova tentativa limitada:

Os seguintes erros são transitórios quando ocorrem durante o estabelecimento da ligação ou ao enviar um pedido para o servidor. Tente novamente após um curto intervalo de espera limitado. Erros que persistem para além de algumas tentativas geralmente indicam um problema de configuração (servidor errado, permissões em falta, quota esgotada) que a tentativa novamente não resolve.

Erro Message Troubleshooting
64 A connection was successfully established with the server, but then an error occurred during the login process. (provider: TCP Provider, error: 0 - The specified network name is no longer available.) A ligação TCP cai a meio do handshake. Não é uma falha de credenciais. Se persistir, verifique se há instabilidade na rede do lado do cliente ou um dispositivo intermédio que interrompa ligações semiestabelecidas.
233 The client was unable to establish a connection because of an error during connection initialization process before login. Falha de transporte pré-login ou TLS. O servidor normalmente devolve-a quando não consegue aceitar a ligação (esgotamento de recursos, ligações máximas atingidas ou um cliente não suportado). Não é uma falha de credenciais. Verifica o estado do servidor e depois verifica o timeout de login do cliente, as definições do TLS e a compatibilidade da versão cliente/servidor TLS.
4060 Cannot open database "%.*ls" requested by the login. The login failed. O login autentica, mas não consegue abrir a base de dados solicitada. Causas transitórias incluem a base de dados estar em transição (failover, restauração, escalabilidade) ou em pausa automática. Causas persistentes (a base de dados não existe, o login não tem acesso) não serão corrigidas por uma nova tentativa; Verifique o nome da base de dados, o mapeamento de login e o estado da base de dados.
4221 Login to read-secondary failed due to long wait on 'HADR_DATABASE_WAIT_FOR_TRANSITION_TO_VERSIONING'. A réplica não está disponível para início de sessão porque as versões de linha estão em falta para transações que estavam em curso quando a réplica foi reciclada. Reverta ou compromete as transações ativas no principal para resolver o problema. Atenue evitando transações de escrita longas no primário.
10053 A transport-level error has occurred when sending the request to the server. (provider: TCP Provider, error: 0 - An established connection was aborted by the software in your host machine.) O lado local interrompe a ligação. Verifique a saúde da rede do lado do cliente e qualquer firewall local ou cliente VPN.
10054 A transport-level error has occurred when sending the request to the server. (provider: TCP Provider, error: 0 - An existing connection was forcibly closed by the remote host.) O lado remoto envia um reset TCP. Causas comuns: o processo peer crashava, um firewall injetava um reset, ou o gateway SQL do Azure fechava uma ligação inativa. Para casos de reposição da ligação por inatividade, ative o keepalive de TCP no cliente ou reduza o tempo limite de inatividade do conjunto de ligações.
10928 Resource ID: %d. The %s limit for the database is %d and has been reached. See 'http://go.microsoft.com/fwlink/?LinkId=267637' for assistance. A base de dados ultrapassa um limite de governação de recursos do SQL do Azure. O ID de Recurso 1 indica o limite de trabalhadores; O ID do Recurso 2 indica o limite de sessão. Identifique o tipo de limite a partir da mensagem, depois reduza a concorrência, escale a base de dados ou encurta as operações de longa duração que detêm o recurso.
10929 Resource ID: %d. The %s minimum guarantee is %d, maximum limit is %d, and the current usage for the database is %d. However, the server is currently too busy to support requests greater than %d for this database. A base de dados ultrapassa a sua garantia mínima e o servidor subjacente está a limitar. Retry normalmente tem sucesso quando a carga do vizinho diminui. Ocorrências prolongadas indicam que precisa de um nível de serviço mais elevado ou de um ambiente menos ruidoso.
40020, 40143, 40166, 40540 Reportado na posição Error code %d do erro 40197 durante a comutação pós-falha. Subcódigos incorporados numa mensagem de failover 40197 que alguns caminhos apresentam como o número de erro de nível superior. Trata-os da mesma forma que 40197.
40197 The service has encountered an error processing your request. Please try again. Error code %d. Uma atualização de software, falha de hardware ou outro evento de failover no SQL do Azure. Ao restabelecer a ligação, será encaminhado para uma réplica em bom estado. O código de erro incorporado identifica o tipo de failover. Se o erro persistir, regista o ID de rastreamento da sessão e contacta o suporte.
40501 The service is currently busy. Retry the request after 10 seconds. Incident ID: %ls. Code: %d. Limitação do motor do SQL do Azure. O intervalo mínimo recomendado é de 10 segundos. A limitação contínua indica que a carga de trabalho excedeu a alocação de recursos da base de dados; aumente o nível de serviço ou reduza o processamento simultâneo.
40613 Database '%.*ls' on server '%.*ls' is not currently available. Please retry the connection later. If the problem persists, contact customer support, and provide them with the session tracing ID of '%.*ls'. A base de dados está indisponível, geralmente a meio do failover ou brevemente durante uma operação de escala. Tente novamente com intervalo progressivo; se o problema persistir durante mais do que alguns minutos, registe o ID de rastreio da sessão e abra um pedido de suporte.
42108 Can not connect to the SQL pool since it is paused. Please resume the SQL pool and try again. O pool dedicado de SQL (Synapse) está em estado de pausa. A nova tentativa só é bem-sucedida depois de o pool ser reativado. Retome explicitamente o pool ou programe a carga de trabalho para ser executada depois de o pool ser retomado.
42109 The SQL pool is warming up. Please try again. O pool dedicado de SQL está a recomeçar. Tente novamente um recuo até a piscina estar online; O aquecimento normalmente demora alguns minutos.
49918 Cannot process request. Not enough resources to process request. The service is currently busy. Please retry the request later. O servidor não consegue atualmente alocar recursos suficientes para satisfazer o pedido. Tente novamente após um intervalo de espera. Se o erro persistir, amplie a base de dados ou o elastic pool.
49919 Cannot process create or update request. Too many create or update operations in progress for subscription "%ld". Limite de concorrência a nível da subscrição para operações de gestão. Reduza as chamadas paralelas de criação/atualização ou escalone-as.
49920 Cannot process request. Too many operations in progress for subscription "%ld". Limite de concorrência ao nível de subscrição para operações em voo. Reduzir o paralelismo ou esperar que as operações em voo se esgotem.

Os erros ao nível da instrução não constam desta lista porque ocorrem depois de a ligação ter sido estabelecida e a falha não inutiliza a sessão. Os erros mais comuns das instruções passíveis de repetição são 1205 (vítima de impasse [deadlock]) e 1222 (tempo limite do pedido de bloqueio). Tente novamente toda a transação em vez do único extrato falhado.

O texto da mensagem de erro provém de erros de ligação transitória do SQL do Azure. Os controladores individuais mantêm as suas próprias listas de repetição integradas; este catálogo descreve os erros passíveis de repetição no SQL Server, no Base de Dados SQL do Azure, no Azure SQL Managed Instance, na Base de Dados SQL no Microsoft Fabric e em pools de SQL dedicados no Azure Synapse Analytics.

Não é possível abrir o servidor (firewall)

Mensagem de erro: mssql: login error: Cannot open server '<server>' requested by the login. Client with IP address '203.0.113.42' is not allowed to access the server.

Causas e soluções:

  • O IP do teu cliente não está nas regras do firewall SQL do Azure. Adicionar uma regra de firewall no portal do Azure: SQL server>Rede>Adicionar uma regra de firewall.
  • Se a sua aplicação está a correr no Azure, ative o Permitir que os serviços e recursos do Azure acedam a este servidor.
  • Para conectividade privada, configure um endpoint privado.

Limite de recursos atingido

Mensagem de erro: mssql: Resource ID: 1. The session limit for the database is 300 and has been reached.

Causas e soluções:

  • Demasiadas ligações simultâneas para o escalão do SQL do Azure. Mais abaixo MaxOpenConns na configuração da tua piscina.
  • Fugas de ligação (linhas ou transações não fechadas). Verifique se faltam chamadas defer rows.Close() ou defer tx.Rollback().
  • Múltiplas aplicações a partilhar a base de dados. Divida o limite de ligação entre todos os clientes.

Para limites de ligação ao SQL do Azure por nível, veja Base de Dados SQL do Azure.

O serviço está atualmente ocupado (limitação)

Mensagem de erro: mssql: The service is currently busy. Retry the request after 10 seconds. Code: 40501.

Causas e soluções:

  • A base de dados está sob grande carga. Implemente uma lógica de repetição com recuo exponencial.
  • A carga de trabalho excede a capacidade de DTU ou de vCore do escalão. Considera aumentar a escala.

Para padrões de implementação de repetição, veja Tratamento de erros e padrões de repetição.

Base de dados atualmente não disponível

Mensagem de erro: mssql: Database 'AdventureWorks2025' on server '<server>' is not currently available. Code: 40613.

Causa: O SQL do Azure está a reconfigurar a base de dados (operação de failover, atualização ou escalabilidade). Esta condição é um erro transitório.

Solução: Tentar novamente a operação. A base de dados normalmente fica disponível em segundos. Para mais informações, consulte Padrões de tratamento de erros e retentativas.

Erros de má ligação

Um driver: bad connection erro significa que o driver detetou que uma ligação existente já não é utilizável. O database/sql pool tenta automaticamente a operação numa ligação nova para chamadas não transacionais, mas as operações dentro de uma transação ativa falham imediatamente.

Não comece por esta secção se a aplicação nunca estabeleceu ligação com sucesso. driver: bad connection normalmente aponta para reutilização de ligação, comutação por falha, tempo limite de inatividade ou interrupções de rede após a ligação inicial já estar estabelecida.

Causas comuns

Motivo Cenário típico Corrigir
tempo limite de inatividade do gateway do SQL do Azure A ligação esteve inativa há mais de 30 minutos por trás do gateway do Azure. Defina db.SetConnMaxIdleTime(2 * time.Minute) para reciclar ligações inativas antes que o gateway as termine.
Interrupção da rede Falha transitória de rede entre o cliente e o servidor. Implementar um mecanismo de repetição para operações não transacionais. Ver Gestão de erros.
Encerramento da sessão no servidor O DBA encerrou a sessão ou o servidor foi reiniciado. Tente novamente. Defina db.SetConnMaxLifetime para alternar as ligações.
Reconfiguração do SQL do Azure O evento de failover, escalabilidade ou patch deixou a ligação cair. Define ConnMaxLifetime para 5 minutos ou menos. Implemente lógica de reintento.
Tempo limite da transação prolongada O SQL do Azure terminou a sessão (erro 40549). Mantenha as transações curtas. Dividir grandes operações em lotes mais pequenos.

Como o database/sql lida com ligações inválidas

Para chamadas fora de uma transação (db.QueryContext, db.ExecContext), o database/sql pool tenta automaticamente a operação numa nova ligação quando o driver reporta uma má ligação. Esta nova tentativa é feita de forma transparente no seu código.

Para chamadas dentro de uma transação (tx.QueryContext, tx.ExecContext), o pool não pode tentar novamente porque o estado da transação é perdido. O seu código tem de detetar o erro, reverter e tentar toda a transação novamente.

Configure o pool para gerir timeouts e failovers do gateway Azure:

db.SetConnMaxLifetime(5 * time.Minute)  // Rotate connections to recover from failovers.
db.SetConnMaxIdleTime(2 * time.Minute)  // Recycle before Azure gateway drops idle connections (30 min).
db.SetMaxIdleConns(10)                  // Keep warm connections for quick recovery.
db.SetMaxOpenConns(20)                  // Stay below your tier's connection limit.

Para o SQL Server local, ConnMaxIdleTime é menos crítico porque não há timeout de inatividade do gateway. No entanto, defini-la evita ligações obsoletas após interrupções de rede.

Para orientações detalhadas de configuração, consulte Base de Dados SQL do Azure.

Exaustão na piscina

O esgotamento do pool ocorre quando todas as ligações estão em uso e os novos chamadores bloqueiam a espera de uma ligação.

Sintomas

  • Os pedidos ficam mais lentos ou excedem o tempo limite sob carga.
  • db.Stats().WaitCount cresce continuamente.
  • db.Stats().InUse igual a MaxOpenConns.
  • O prazo de contexto excedeu os erros durante o pico de tráfego.

Diagnóstico

Adicione monitorização de pools à sua aplicação:

stats := db.Stats()
log.Printf("Pool: open=%d inUse=%d idle=%d waitCount=%d waitDuration=%v",
    stats.OpenConnections, stats.InUse, stats.Idle,
    stats.WaitCount, stats.WaitDuration)

Causas comuns e soluções

Motivo Como identificar Corrigir
rows.Close() não invocado InUse Cresce com o tempo, nunca diminui. Adicione defer rows.Close() após cada QueryContext.
Transações de longa duração InUse mantém-se elevado durante o processamento em lote. Mantenha as transações curtas. Processe grandes lotes em pedaços mais pequenos.
MaxOpenConns demasiado baixo WaitCount cresce de forma constante sob carga normal depois de excluir recursos bloqueados e fugas. Aumente MaxOpenConns.
MaxOpenConns não definido Centenas de conexões abertas sob carga de pico. Defina MaxOpenConns como um valor limitado.
Fuga de goroutines ao chamar db.Conn InUse cresce sem um aumento correspondente dos pedidos. Certifique-se de que cada resultado db.Conn() seja fechado com defer conn.Close().

Para orientações detalhadas sobre a configuração do pool, veja Connection pooling.

Diagnósticos de consulta lentos ou bloqueados

Definir tempos de espera de consulta

Use prazos contextuais para identificar consultas lentas e evitar que chamadas SQL bloqueadas prendam as ligações e atrasem os chamadores:

ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

rows, err := db.QueryContext(ctx, "SELECT * FROM LargeTable WHERE Status = @s",
    sql.Named("s", "active"))
if err != nil {
    // Check if the error was a timeout.
    if ctx.Err() == context.DeadlineExceeded {
        log.Println("Query exceeded 5-second timeout")
    }
    return err
}
defer rows.Close()

Para um fluxo de trabalho completo para investigação do desempenho, incluindo Query Store, DMVs, análise de índices em falta e avaliação comparativa, consulte Otimização do desempenho.

Diagnóstico de interbloqueios

Mensagem de erro: mssql: Transaction (Process ID 52) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

Erro número: 1205

Solução: Bloqueios ocorrem em sistemas concorrentes. Implementar lógica de nova tentativa automática para o erro 1205. Para uma função encapsuladora para repetição em caso de impasse, consulte Transações.

Estratégias de prevenção:

  • Acede às tabelas pela mesma ordem em todas as consultas.
  • Mantenha as transações curtas e evite a interação do utilizador durante as transações.
  • Utilize o isolamento READ COMMITTED SNAPSHOT para reduzir a contenção de bloqueio.

Bloqueios repetidos na mesma consulta indicam um problema de design. Utilize o gráfico de impasse (capturado através de Eventos Estendidos ou da sessão de estado de funcionamento do sistema) para identificar as instruções em conflito e os tipos de bloqueio. Para um guia completo, consulte o guia de Deadlocks. Para estratégias de manuseamento de deadlocks em Go, veja Deadlock handling e Handle deadlocks.

Erros de certificado com contentores (Go 1.23 e versões posteriores)

Mensagem de erro: x509: negative serial number

Causa: O Go 1.23 aplica rigorosamente o RFC 5280. O certificado autoassinado que o SQL Server gera em contentores Docker usa um número de série negativo, que o Go rejeita.

Soluções:

  • Para ambientes de teste, adicione TrustServerCertificate=true para saltar a validação de certificados ou encrypt=disable desligar completamente a encriptação.
  • Para CI/CD, define a GODEBUG=x509negativeserial=1 variável de ambiente para restaurar o comportamento pré-Go 1.23 sem mudar a tua cadeia de ligação.
  • Em go.mod (Go 1.23 e versões posteriores), adicione uma diretiva godebug x509negativeserial=1 para aplicar a substituição em tempo de compilação.

Caution

Não uses TrustServerCertificate=true ou encrypt=disable em produção. Estas opções desativam as verificações de segurança. Para produção, use um certificado devidamente assinado.

Erros de certificado SHA-1 (Go 1.24 e versões posteriores)

Mensagem de erro: tls: handshake failure ou TLS Handshake failed: EOF ao ligar a instâncias antigas do SQL Server.

Causa: O Go 1.24 impede por defeito algoritmos de assinatura SHA-1 em certificados TLS. Versões mais antigas do SQL Server e algumas instalações on-premises utilizam certificados assinados com SHA-1.

Soluções:

  • Reemita o certificado do servidor com SHA-256 ou posterior (recomendado).
  • Defina a GODEBUG=tlssha1=1 variável de ambiente para reativar temporariamente o suporte ao SHA-1.
  • Em go.mod (Go 1.23 e versões posteriores), adicione a diretiva godebug tlssha1=1.

Quando usar encrypt=disable vs. TrustServerCertificate=true

Setting O que faz Quando utilizar
TrustServerCertificate=true Encripta o tráfego mas ignora a validação de certificados. Desenvolvimento local e testes onde o servidor utiliza um certificado auto-assinado.
encrypt=disable Envia tráfego em texto simples (sem TLS). Ambientes legados onde o TLS não está disponível. Não recomendado.
encrypt=strict TDS 8.0 com validação TLS completa a partir do primeiro byte. Produção em SQL Server 2022 ou SQL do Azure.

Para mais informações, consulte Testes e Encriptação e certificados.

Questões de codificação e colação

Avisos de conversão implícita

Se passar string parâmetros (enviados como nvarchar) para varchar colunas, o SQL Server efetua uma conversão implícita que pode impedir a utilização de índices.

Este exemplo dá continuidade à configuração com database/sql e mssql de excertos anteriores deste artigo.

Solução: Uso mssql.VarChar para varchar colunas:

db.QueryContext(ctx, "SELECT * FROM Production.Product WHERE ProductNumber = @p1",
    mssql.VarChar("FR-R92B-58"))

Erro CharsetToUTF8 ao processar caracteres não latinos

Mensagem de erro: CharsetToUTF8: ... ao consultar varchar colunas contendo caracteres chineses, japoneses ou outros caracteres não latinos armazenados numa colação como SQL_Latin1_General_CP1_CI_AS.

Causa: O driver tenta converter a página de códigos da coluna para UTF-8, mas os bytes armazenados não correspondem à codificação esperada da colação.

Soluções:

  • Use nvarchar em vez de varchar para colunas que armazenam texto não latino. nvarchar armazena dados como UTF-16 e evita a conversão de páginas de códigos.
  • Se não conseguires alterar o tipo de coluna, verifica se a colação da base de dados suporta o conjunto de caracteres que estás a armazenar.

Ativar registo de diagnóstico

Utilize o parâmetro de ligação log para ativar o registo ao nível do controlador:

sqlserver://<user>:<password>@<server>?database=AdventureWorks2025&log=63

As flags de log são valores de bitmask: 1 (erros), 2 (mensagens), 4 (linhas), 8 (SQL), 16 (parámetros), 32 (transações), 64 (depuração). Combina valores somando-os (por exemplo, 63 = todos exceto debug, 127 = todos).

Para registo programático, use SetLogger ou SetContextLogger. Veja Registo e diagnóstico.

Lista de verificação para resolução de problemas

Symptom Primeiro passo
Ligação recusada Verifica se o SQL Server está a correr e o TCP/IP está ativado.
Início de sessão falhado Verifique credenciais e modo de autenticação.
Erro de certificado Verifica o certificado do servidor ou o conjunto TrustServerCertificate=true (apenas para desenvolvedores).
Tempo limite de ligação Verifique o caminho da rede com Test-NetConnection. Verificar as regras de firewall.
Firewall do SQL do Azure Adicione o seu IP às regras de firewall SQL do Azure.
Erros de limitação Implemente uma nova tentativa com atraso exponencial. Aumente o escalão.
Má ligação Defina ConnMaxIdleTime abaixo dos 30 minutos para SQL do Azure. Implemente lógica de reintento.
Exaustão na piscina Monitorizar db.Stats(). Corrigir linhas/transações não encerradas. Aumente MaxOpenConns.
Consultas lentas Define tempos de espera de contexto. Consulte os DMVs para consultas caras.
Deadlocks Implementar nova tentativa em caso de erro 1205. Aceder às tabelas por ordem consistente.
Conversão implícita Utilize mssql.VarChar para varchar colunas.