go-mssqldbドライバーのトラブルシューティング

この記事では、 go-mssqldb ドライバーの一般的なエラーや接続問題の解決策を提供します。

最も簡単なチェックから始めましょう

詳細ログを有効にしたりプール設定を変更したりする前に、以下のリストを進めてください:

  1. 基本的な到達可能性を確認しましょう:サーバー名、ポート、ファイアウォールルール、SQL ServerまたはAzure SQLが接続を受け付けているかどうか。
  2. 認証入力:ドライバー名、ユーザー名、パスワード、ドメインフォーマット、 fedauth 設定を確認してください。
  3. TLSの設定: encrypt、証明書経路、 hostnameincertificate、環境に適しているかどうか TrustServerCertificate 確認してください。
  4. 接続設定が正しいことを確認してから、コネクションプールの枯渇、古い接続、再試行ロジック、低速またはブロックされたクエリの診断について調査してください。

この記事の冒頭部分は接続設定の失敗について参考にしてください。 接続が少なくとも時々成功し、負荷やアイドル時間、フェイルオーバー時に故障した場合のみ後半のセクションを使用してください。

接続エラー

以下のセクションでは、よくある接続関連のエラーメッセージとその解決策について説明します。

TCP接続を開けない

エラー メッセージ: 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.

原因と解決策:

  • SQL Serverは動いていません。 SQL Server サービスを開始します。
  • TCP/IPは有効になっていません。 SQL Server 構成マネージャーを開き、SQL Server Network Configuration>Protocols で TCP/IP を有効にしてください。
  • 間違ったポートだ。 名前付きインスタンスについてはSQL Server 構成マネージャーでポートを確認するか、SQL Server Browserを使ってください。
  • ファイアウォールがポートをブロックしています。 ポート1433(または設定済みポート)にインバウンドルールを追加してください。

ユーザーはログインできませんでした

エラー メッセージ: mssql: login error: Login failed for user '<user>'.

原因と解決策:

  • ユーザー名やパスワードが間違っています。 資格を確認してください。
  • SQL Server認証は無効になっています。 サーバープロパティでSQL ServerとWindows認証モードを有効にしてください。
  • ログインは存在しません。 SQL Serverでログインを作成します。
  • ログインはターゲットのデータベースにアクセスできません。 CREATE USERでデータベースアクセスを許可してください。

証明書の検証エラー

エラー メッセージ: TLS Handshake failed: x509: certificate signed by unknown authority

原因と解決策:

  • サーバーは自己署名証明書を使用します。 証明書パスに certificate または serverCertificate パラメータを付与するか、開発専用の TrustServerCertificate=true を設定してください。
  • CAの証明書はシステムトラストストアにはありません。 CA証明書をOSトラストストアに追加するか、 certificate パラメータで指定してください。
  • ホスト名の不一致。 hostnameincertificateを使って証明書に期待される名前を指定します。

詳細については、「 暗号化と証明書」をご覧ください。

接続がタイムアウトしました

エラー メッセージ: unable to open tcp connection with host '<server>:1433': dial tcp: i/o timeout

原因と解決策:

  • ネットワーク接続の問題。 telnet <server> 1433Test-NetConnection -ComputerName <server> -Port 1433を使ってサーバーにアクセスできるか確認してください。
  • DNS解決の失敗。 ホスト名が正しく解決されているか確認してください。
  • その接続文字列で、dial timeoutconnection timeoutを増やしましょう。

認証エラー

以下のセクションでは認証エラーメッセージについて説明します。

NTLM認証失敗

エラー メッセージ: NTLM authentication failed

原因と解決策:

  • ドメインフォーマットが間違っています。 DOMAIN\userパラメータでuser idを使いましょう。 URL形式でバックスラッシュを %5Cとしてエンコードします。
  • パスワードが間違ってる。 ドメインパスワードを確認してください。

Kerberos 認証エラー

エラー メッセージ: krb5: cannot resolve KDC for realm

原因と解決策:

  • /etc/krb5.confが欠けているか、設定が誤っている。 [realms]セクションにドメインの正しいKDCアドレスが含まれているか確認してください。
  • 有効なチケットはありません。 有効なチケットを確認するために klist 走るか、チケットを入手するために kinit 走ってください。
  • キータブファイルが見つかりません。 krb5-keytabfileパラメータの経路を確認します。

詳細については、SQL ServerおよびWindows 認証をご覧ください。

Microsoft Entra ID認証の失敗

エラーメッセージ: clientCredentialFromCert: error reading certificate: ... または DefaultAzureCredential: failed to acquire a token

原因と解決策:

  • 間違ったクライアントID、テナントID、またはクライアントシークレット。 接続文字列やenvironment変数の値を検証してください。
  • ホスト側では管理されたアイデンティティが設定されていません。 Azureポータルで本人確認をしてください。
  • パッケージのインポート azuread 欠落しています。 github.com/microsoft/go-mssqldb/azureadをインポートして、azuresqlドライバー名を使いましょう。

詳細については、「 Microsoft Entra ID 認証」を参照してください。

ユーザー ''(空のユーザー名)でログインが失敗しました

エラー メッセージ: mssql: login error: Login failed for user ''.

原因:sql.Open("sqlserver", ...)パラメータ付きのfedauthを使いましたね。 Entra ID認証には、azuresqlパッケージによって登録されたazureadドライバー名が必要です。 標準 sqlserver ドライバでは fedauth パラメータを無視し、ユーザー名なしでSQL認証を試みます。

解決策: azuread パッケージをインポートし、 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)
}

詳細については、「 Microsoft Entra ID 認証」を参照してください。

クエリエラー

以下のセクションでは、クエリ実行エラーメッセージについて扱います。

LastInsertIDはサポートされていません

エラー メッセージ: LastInsertId is not supported. Please use the OUTPUT clause or add 'select ID = convert(bigint, SCOPE_IDENTITY())' to the end of your query.

解決策:go-mssqldbドライバーはLastInsertId()をサポートしていません。 OUTPUT節やクエリSCOPE_IDENTITY()別に使う。

一時テーブルが見つかりません

エラー メッセージ: mssql: Invalid object name '#TempTable'.

原因:一時テーブルは接続ごとに割り当てられています。 一つのコールで一時テーブルを作成し、別のコールでそのテーブルをクエリすると、接続プールから異なる接続が使用される可能性があります。

解決策: db.Conn(ctx) を使って単一の接続にピン留めしたり、トランザクション内で操作をラップします。

詳細については、「 ストアド プロシージャ」を参照してください。

Azure SQL のエラー

以下のセクションでは、Azure SQL Database特有のエラーを扱います。

一時接続エラー番号

以下の共有リストを、境界再試行の対象となる一時的な接続確立エラーおよびリクエストパストランスポート障害の参照としてご利用ください。

次のエラーは、接続の確立中またはサーバーへの要求の送信中に発生した一時的なエラーです。 短い境界付きバックオフで再試行します。 再試行回数を超えてエラーが続く場合は、通常、構成の問題 (間違ったサーバー、アクセス許可の不足、クォータの不足) が発生しても、再試行は修正されません。

エラー メッセージ 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.) TCP 接続がハンドシェイクの途中で切断されます。 認証情報エラーではありません。 それでも解決しない場合は、クライアント側のネットワークが不安定であるか、または半分確立された接続を切断する中間デバイスを確認します。
233 The client was unable to establish a connection because of an error during connection initialization process before login. ログイン前トランスポートまたは TLS エラー。 サーバーは通常、接続を受け入れることができない場合 (リソースの枯渇、最大接続に達した場合、またはサポートされていないクライアント) にそれを返します。 認証情報エラーではありません。 サーバーの正常性を確認し、クライアント ログインのタイムアウト、TLS 設定、およびクライアント/サーバーの TLS バージョンの互換性を確認します。
4060 Cannot open database "%.*ls" requested by the login. The login failed. ログインは認証されますが、要求されたデータベースを開くことはありません。 一時的な原因には、データベースの移行中 (フェールオーバー、復元、スケーリング) や自動一時停止が含まれます。 永続的な原因 (データベースが存在せず、ログインにアクセスできない) は再試行によって修正されません。データベース名、ログイン マッピング、およびデータベースの状態を確認します。
4221 Login to read-secondary failed due to long wait on 'HADR_DATABASE_WAIT_FOR_TRANSITION_TO_VERSIONING'. レプリカがリサイクルされたときに実行中だったトランザクションに対して行バージョンが見つからないため、レプリカはログインに使用できません。 プライマリでアクティブなトランザクションをロールバックまたはコミットして、問題を解決します。 プライマリで長い書き込みトランザクションを回避することで軽減します。
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.) ローカル側が接続を中止します。 クライアント側のネットワーク正常性と、ローカル ファイアウォールまたは 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.) リモート側は TCP リセットを送信します。 一般的な原因: ピア プロセスがクラッシュした、ファイアウォールがリセットを挿入した、またはAzure SQLゲートウェイがアイドル状態の接続を閉じた。 アイドル リセット パターンの場合は、クライアントで TCP キープアライブを有効にするか、接続プールのアイドル タイムアウトを短縮します。
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. データベースがAzure SQLリソース ガバナンスの制限を超えています。 リソース ID 1 はワーカーの制限を示します。リソース ID 2 は、セッションの制限を示します。 メッセージから制限の種類を特定し、コンカレンシーを減らすか、データベースをスケールアップするか、リソースを保持する実行時間の長い操作を短縮します。
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. データベースは最小保証を超過しており、基盤となるサーバーでスロットル制御が行われています。 再試行は通常、近隣の負荷が低下したときに成功します。 継続的な発生は、より高いサービス レベルまたはノイズの少ない環境が必要であることを示します。
40020401434016640540 フェールオーバー中にエラー 40197 の Error code %d スロットで報告されました。 一部のパスが最上位のエラー番号として表示される 40197 フェールオーバー メッセージに埋め込まれたサブコード。 40197 と同じように扱います。
40197 The service has encountered an error processing your request. Please try again. Error code %d. Azure SQLでのソフトウェアのアップグレード、ハードウェア障害、またはその他のフェールオーバー イベント。 再接続すると、正常なレプリカにルーティングされます。 埋め込みエラー コードは、フェールオーバーの種類を識別します。 エラーが解決しない場合は、セッション トレース ID をキャプチャし、サポートにお問い合わせください。
40501 The service is currently busy. Retry the request after 10 seconds. Incident ID: %ls. Code: %d. Azure SQL Engine のスロットリング。 推奨されるバックオフの下限は 10 秒です。 継続的なスロットリングは、ワークロードがデータベースのリソース割り当てを超過していることを示しています。サービス レベル階層をスケールアップするか、同時実行数を減らします。
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'. データベースは使用できません。通常はフェールオーバー中、またはスケール操作中に短時間です。 バックオフ時に再試行します。数分後に保持される場合は、セッション トレース ID をキャプチャし、サポート ケースを開きます。
42108 Can not connect to the SQL pool since it is paused. Please resume the SQL pool and try again. 専用 SQL プール (Synapse) は一時停止状態です。 再試行は、プールが再開された後にのみ成功します。 プールを明示的に再開するか、プールの再開後にワークロードを実行するようにスケジュールします。
42109 The SQL pool is warming up. Please try again. 専用 SQL プールが再開中です。 プールがオンラインになるまでバックオフを再試行します。ウォームアップには通常数分かかります。
49918 Cannot process request. Not enough resources to process request. The service is currently busy. Please retry the request later. サーバーは現在、要求を満たすのに十分なリソースを割り当てられません。 バックオフ時に再試行してください。 エラーが解決しない場合は、データベースまたはエラスティック プールをスケールアップします。
49919 Cannot process create or update request. Too many create or update operations in progress for subscription "%ld". 管理操作に対するサブスクリプション レベルのコンカレンシー制限。 並列作成/更新呼び出しを減らすか、それらをずらします。
49920 Cannot process request. Too many operations in progress for subscription "%ld". 実行中の操作に対するサブスクリプション レベルでの同時実行制限。 並列処理を減らすか、進行中の操作が完了するまで待機してください。

ステートメント レベルのエラーは、接続が確立された後に発生し、エラーによってセッションが使用可能な状態になるため、この一覧には含まれません。 再試行可能な最も一般的なステートメント エラーは、1205 (デッドロックの対象) と 1222 (ロック要求タイムアウト) です。 単一の失敗したステートメントではなく、トランザクション全体を再試行してください。

エラー メッセージ テキストはAzure SQL の一時的な接続エラーから取得されます。 個々のドライバーは、それぞれ独自の組み込み再試行リストを備えています。このカタログでは、SQL Server、Azure SQL Database、Azure SQL Managed Instance、Microsoft Fabric の SQL データベース、および Azure Synapse Analytics の専用 SQL プールにおいて、どのエラーが再試行の対象となるかについて説明します。

サーバー(ファイアウォール)を開けません

エラー メッセージ: 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.

原因と解決策:

  • クライアントのIPアドレスはAzure SQLファイアウォールのルールに含まれていません。 Azureポータルにファイアウォールルールを追加してください:SQL Server>Networking>ファイアウォールルールを追加してください。
  • アプリケーションがAzure上で動作している場合は、「このサーバーへのアクセスにAzureサービスとリソースを許可する」を有効にしてください。
  • プライベート接続の場合は、プライベートエンドポイントを設定してください。

リソースの制限に達しました

エラー メッセージ: mssql: Resource ID: 1. The session limit for the database is 300 and has been reached.

原因と解決策:

  • Azure SQL tierには同時接続が多すぎます。 プールの配置で MaxOpenConns を下げましょう。
  • 接続漏れ(未閉鎖行やトランザクション)。 defer rows.Close()defer tx.Rollback() の呼び出しが欠けていないか確認してください。
  • 複数のアプリケーションがデータベースを共有しています。 接続制限をすべてのクライアントで分割してください。

tierごとのAzure SQL接続制限については、Azure SQL Databaseを参照してください。

現在、サービスは混雑しています(スロットリング中)

エラー メッセージ: mssql: The service is currently busy. Retry the request after 10 seconds. Code: 40501.

原因と解決策:

  • データベースは大きな負荷がかかっています。 指数バックオフを使用した再試行ロジックを実装します。
  • ワークロードはその階層のDTUやvCore容量を超えています。 スケールアップを検討してください。

リトライ実装パターンについては、 エラー処理およびリトライパターンを参照してください。

現在利用可能なデータベースではありません

エラー メッセージ: mssql: Database 'AdventureWorks2025' on server '<server>' is not currently available. Code: 40613.

原因:Azure SQLがデータベースの再構成(フェイルオーバー、更新、スケーリング操作)を行っています。 この状態は一時的な誤差です。

解決策:手術をやり直す。 データベースは通常、数秒以内に利用可能になります。 詳細は「 エラー処理および再試行パターン」をご覧ください。

接続不良エラー

driver: bad connectionエラーは、既存の接続が使えなくなったことをドライバーが検出したことを意味します。 database/sqlプールは非トランザクション呼び出しに対して新しい接続で自動的に操作を再試行しますが、アクティブなトランザクション内の操作は即座に失敗します。

もしアプリケーションが成功裏に接続できなかったなら、このセクションから始めないでください。 driver: bad connection 通常、接続の再利用、フェイルオーバー、アイドルタイムアウト、または初期接続がすでに動作した後のネットワーク中断を示します。

一般的な原因

原因 一般的なシナリオ 修正
Azure SQL ゲートウェイのアイドル タイムアウト Azure ゲートウェイ経由で、接続が 30 分以上アイドル状態です。 ゲートウェイがアイドル接続を切断する前に db.SetConnMaxIdleTime(2 * time.Minute) をリサイクルするように設定してください。
ネットワークの中断 クライアントとサーバー間の一時的なネットワーク障害。 非トランザクション操作のためにリトライロジックを実装します。 エラー 処理を参照してください。
サーバー側セッション終了 DBAがセッションを終了するか、サーバーが再起動されたのです。 再試行してください。 db.SetConnMaxLifetimeを接続を回転させるように設定してください。
Azure SQL の再構成 フェイルオーバー、スケーリング、パッチのイベントで接続が切れました。 ConnMaxLifetime を 5 分以下に設定してください。 再試行ロジックを実装します。
長時間実行トランザクションのタイムアウト Azure SQL によりセッションが終了しました (エラー 40549)。 取引は短くしましょう。 大規模な操作をより小さなバッチに分割します。

データベースやSQLが悪い接続をどのように扱うか

トランザクション外の呼び出し(db.QueryContextdb.ExecContext)の場合、ドライバが接続不良を報告すると、 database/sql プールは新しい接続で自動的に操作を再試行します。 この再試行は、コード側で意識することなく行われます。

トランザクション内の呼び出し(tx.QueryContexttx.ExecContext)では、トランザクション状態が失われているためプールは再試行できません。 コードがエラーを検出し、ロールバックしてトランザクション全体を再試行しなければなりません。

プールを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.

オンプレミスでの SQL Server では、ゲートウェイのアイドルタイムアウトがないため、ConnMaxIdleTime の重要性は低いです。 ただし、それを設定することで、ネットワーク障害後に古い接続が残るのを防げます。

詳細な設定ガイダンスについては、Azure SQL Databaseをご覧ください。

プールの枯渇

プールの枯渇は、プール内のすべての接続が使用中であり、新規発信者が接続待ちをブロックするときに発生します。

Symptoms

  • リクエストは負荷がかかると遅くなったりタイムアウトしたりします。
  • db.Stats().WaitCount 継続的に成長します。
  • db.Stats().InUseMaxOpenConnsと等しくなります。
  • ピーク時のコンテキスト期限はエラーを上回りました。

診断

プールモニタリングをアプリケーションに追加:

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)

一般的な原因と解決策

原因 特定する方法 修正
rows.Close() 呼び出されない InUse 時間とともに成長し、決して減少しません。 defer rows.Close()ごとにQueryContextを加えましょう。
長時間トランザクション InUse はバッチ処理中も高い状態を維持します。 取引は短くしましょう。 大量のロットを小さな塊に分けて処理しましょう。
MaxOpenConns 低すぎる WaitCount は、固定されたリソースやリークを除外すると、通常負荷下で着実に増加します。 MaxOpenConnsを増やします。
MaxOpenConns 設定されていません スパイク負荷時の数百件のオープン接続 MaxOpenConnsを有界値に設定します。
db.Conn 呼び出し時のゴルーチンリーク InUse は、対応するリクエストの増加なしに増加します。 すべての db.Conn() 結果が defer conn.Close()でクローズされていることを確認してください。

詳細なプール設定のガイダンスについては 、接続プーリングをご覧ください。

遅いまたはブロックされたクエリ診断

クエリのタイムアウトを設定する

コンテキストの締め切りを利用して遅いクエリを特定し、ブロックされたSQL呼び出しが接続をピン留めしたり呼び出し元を停止させたりするのを防ぎましょう:

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()

クエリ ストア、DMV、欠損インデックス分析、ベンチマークを含む完全なパフォーマンス調査ワークフローについては、Performance tuningを参照してください。

デッドロック診断

エラー メッセージ: mssql: Transaction (Process ID 52) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

エラー番号:1205

解決策:デッドロックは並行システムで発生します。 エラー1205の自動再試行ロジックを実装してください。 デッドロックの再試行ラッパー関数については 、トランザクションを参照してください。

予防戦略:

  • すべてのクエリで同じ順序でテーブルにアクセスできます。
  • 取引は短くし、取引中のユーザー操作は避けましょう。
  • READ COMMITTED SNAPSHOTアイソレーションを使ってロックの競合を減らす。

同じクエリで繰り返しデッドロックが起きる場合は設計上の問題を示しています。 デッドロックグラフ(拡張イベントやシステムヘルスセッションを通じてキャプチャ)を使って競合する文やロックタイプを特定します。 詳細な攻略は Deadlocksガイドをご覧ください。 Goにおけるデッドロック処理戦略については、 Deadlock handling および Handle deadlock を参照してください

コンテナに関する証明書エラー(Go 1.23以降のバージョン)

エラー メッセージ: x509: negative serial number

原因:Go 1.23はRFC 5280を厳格に適用しています。 SQL ServerがDockerコンテナで生成する自己署名証明書は負のシリアル番号を使用しますが、Goはこれを拒否します。

解決策:

  • テスト環境では、証明書検証をスキップする TrustServerCertificate=true を追加したり、暗号化を完全にオフにする encrypt=disable を設けてください。
  • CI/CDの場合は、GODEBUG=x509negativeserial=1環境変数を設定して、接続文字列を変えずにGo 1.23以前の動作を復元します。
  • go.mod(Go 1.23以降のバージョン)では、ビルド時にオーバーライドを適用するgodebug x509negativeserial=1ディレクティブを追加してください。

注意事項

本番環境で TrustServerCertificate=trueencrypt=disable は使わないでください。 これらのオプションはセキュリティチェックを無効にします。 本番環境では、適切に署名された証明書を使用してください。

SHA-1証明書エラー(Go 1.24以降のバージョン)

エラーメッセージ:古いSQL Serverインスタンスに接続時にtls: handshake failureまたはTLS Handshake failed: EOF

原因:Go 1.24では、TLS証明書にSHA-1署名アルゴリズムをデフォルトで禁止しています。 古いSQL Serverのバージョンや一部のオンプレミスインストールでは、SHA-1で署名された証明書を使用しています。

解決策:

  • サーバー証明書はSHA-256以降のもので再発行してください(推奨)。
  • GODEBUG=tlssha1=1環境変数を設定してSHA-1のサポートを一時的に再有効にします。
  • go.mod(Go 1.23以降のバージョン)では、godebug tlssha1=1ディレクティブを追加してください。

encrypt=disableを使うべきタイミングとTrustServerCertificate=true

設定 それが何をするか いつ使用するか
TrustServerCertificate=true トラフィックは暗号化しますが、証明書の検証はスキップします。 サーバーが自己署名証明書を使用するローカル開発とテスト。
encrypt=disable トラフィックは平文で送信します(TLSなし)。 TLSが利用できないレガシー環境。 お勧めしません。
encrypt=strict TDS 8.0で、最初のバイトから完全なTLS検証が行われています。 SQL Server 2022 または Azure SQL での運用環境。

詳細については、「 テスト暗号化および証明書」をご覧ください。

符号化およびコレーションの問題

暗黙の変換警告

stringパラメータ(nvarcharとして送信)をvarchar列に渡すと、SQL Server暗黙の変換を行い、インデックス使用を妨げる可能性があります。

この例は、この記事の以前の断片で示した database/sqlmssql の設定を継続しています。

解決策: varchar列にはmssql.VarCharを使用します。

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

非ラテン文字を含むCharsetToUTF8エラー

エラーメッセージ:中国語、日本語、その他の非ラテン文字を含む列をCharsetToUTF8: ...照会する際にvarcharSQL_Latin1_General_CP1_CI_ASのようなコレーションで格納されます。

原因:ドライバーが列のコードページをUTF-8に変換しようとしますが、保存されたバイトがコレーションの期待されるエンコーディングと一致しません。

解決策:

  • 非ラテン語テキストを格納する列には、nvarcharの代わりにvarcharを使いましょう。 nvarchar データをUTF-16として保存し、コードページの変換を回避します。
  • 列の種類を変えられない場合は、データベースのコレーションが保存している文字セットに対応しているか確認してください。

診断ログの有効化

ドライバーレベルのログングを有効にするには log 接続パラメータを使用します:

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

ログフラグはビットマスクの値です: 1 (エラー)、 2 (メッセージ)、 4 (行)、 8 (SQL)、 16 (パラメータ)、 32 (トランザクション)、 64 (デバッグ)。 値を加算して組み合わせます(例: 63 = デバッグ以外の全員、 127 = すべて)。

プログラムログの場合は SetLogger または SetContextLoggerを使いましょう。 「ログ記録と診断」を参照してください。

トラブルシューティング チェックリスト

症状: 最初の手順
接続が拒否されました SQL Serverが稼働していてTCP/IPが有効になっているか確認してください。
ログインに失敗しました 認証情報と認証モードを確認してください。
証明書のエラー サーバー証明書かセット TrustServerCertificate=true (開発者専用)を確認してください。
接続タイムアウト ネットワークパスを Test-NetConnectionで確認してください。 ファイアウォール規則を確認します。
Azure SQL ファイアウォール Azure SQLのファイアウォールルールにIPアドレスを追加してください。
スロットリングエラー 指数的なバックオフ付きのリトライを実装してください。 階層を上げましょう。
接続不良 Azure SQL では ConnMaxIdleTime30 分未満に設定してください。 再試行ロジックを実装します。
プールの枯渇 db.Stats()を監視してください。 閉じられていない行やトランザクションを修正してください。 MaxOpenConnsを増やします。
低速クエリ コンテキストタイムアウトを設定しましょう。 高額な問い合わせはDMVに問い合わせてください。
デッドロック エラー1205の再試行を実装してください。 テーブルへのアクセスは一貫した順序で。
暗黙的な型変換 mssql.VarChar列にはvarcharを使いましょう。