ODBCドライバーでCおよびC++アプリケーションを開発

バージョン: 18.7.1.1
日付:2026年9月7日

CまたはC++からODBC APIを呼び出すには、 sql.h、 sqlext.h、 sqltypes.hを含め、ドライバーマネージャーのインポートライブラリに対してリンクしてください。 Microsoft ODBC Driver for SQL Server が ODBC 標準に追加する SQL Server 拡張機能を使用するには、msodbcsql.h もインクルードし、コア ODBC ヘッダーの後に配置してください。

適用対象: Windows、Linux、macOS 上の Microsoft ODBC Driver 18 for SQL Server。 バージョン17は同じヘッダー名にインストールパス 170 、ライブラリ名 msodbcsql17 を使用します。

ヘッダーとライブラリ

プラットフォームはドライバーパッケージではなく、コアのODBCヘッダーとドライバーマネージャーを提供します。 WindowsではWindows SDKが付属しています。 LinuxとmacOSでは、UnixODBC開発パッケージに同梱されています。 ドライバーSDKは msodbcsql.h と一括コピーインポートライブラリのみを提供しています。

あなたがそう呼んでいるもの ヘッダー Windows Linux macOS
ODBC API sql.h、sqlext.h、sqltypes.h odbc32.lib -lodbc -lodbc
ODBC API、Unicodeエントリポイント sqlucode.hを追加する odbc32.lib -lodbc -lodbc
ODBC インストーラー API odbcinst.hを追加する odbccp32.lib -lodbcinst -lodbcinst
SQL Server ドライバー拡張 msodbcsql.hを追加する 追加のライブラリはありません 追加のライブラリはありません 追加のライブラリはありません
一括コピー (bcp_*) 機能 msodbcsql.hを追加する msodbcsql18.lib -lmsodbcsql-18 -lmsodbcsql.18

ファイル名が異なるため、一括コピーリンク名はプラットフォームによって異なります。 Linuxでは、-lmsodbcsql-18は/usr/libのlibmsodbcsql-18.soシンムリンクで解決され、リンカーはすでに検索しているので、-Lは不要です。 macOSではドライバーが libmsodbcsql.18.dylibとして出荷され、 -lmsodbcsql.18 一致しますが、HomebrewのライブラリディレクトリはAppleシリコンのデフォルトの検索パスには含まれていません。 一括コピー機能をリンクするときにも -L$(brew --prefix)/lib を追加してください。

ドライバー専用ライブラリが必要なのは一括コピー関数だけです。 接続属性、文属性、列属性、SQL Server型識別子はマクロや型定義なので、msodbcsql.h含めるだけで十分です。

インストーラーAPIはODBC APIとは別のライブラリです。 LinuxやmacOSで-lodbcinstなしにSQLGetPrivateProfileStringのような関数を呼び出すと、リンク時には参照が定義されていない状態で失敗しますが、コンパイル時には失敗しません。

LinuxおよびmacOSでコアヘッダーを提供するunixODBC開発パッケージをインストールするには、「 Install the unixODBC driver manager」をご覧ください。

Linux および macOS 上の C コードでは、msodbcsql.h より前に wchar.h をインクルードしてください

Linux版およびmacOS版 msodbcsql.h は wchar_tを使ってAlways Encryptedキーストアプロバイダーインターフェースを宣言していますが、このタイプを定義するヘッダーは含まれていません。 C++では wchar_t がキーワードであるため、追加のヘッダーを必要とせずにC++の翻訳ユニットを構築できます。 Cでは wchar_t タイプdefなので、Cの翻訳単位でまず <wchar.h> を含める必要があります:

#include <wchar.h>

<wchar.h>を含めなければ、コンパイラはmsodbcsql.h内部からunknown type name 'wchar_t'エラーを報告します。 インクルーブの追加はWindowsでは無害なので、プラットフォームガードの後ろに置くのではなく、共有ソースに追加してください。

コアODBCヘッダーの後にmsodbcsql.hを含めてください

ドライバー名マクロ以外 msodbcsql.h 定義するものはすべて #ifdef ODBCVER ブロックの中にあり、 sql.h が ODBCVERを定義します。 msodbcsql.hを先に含めると、プリプロセッサはそのブロック全体をスキップし、ヘッダーは何も貢献しません。 コンパイラは警告を出しません。

/* Correct order. */
#ifdef _WIN32
#include <windows.h>
#endif

#include <wchar.h>
#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>
#include <msodbcsql.h>

ODBCVER の前に msodbcsql.h を含めると、sql.h ブロック内のすべてが未定義のままになります。 コンパイラは使用時にエラーを報告し、include時には報告しません。

order-wrong.c(7): error C2065: 'SQL_COPT_SS_BCP': undeclared identifier

Windowsでは、ODBCヘッダーの前にwindows.hを含める必要があります。 sqltypes.h と sql.h の Windows SDK 版のコピーでは、DWORD や LONG などの Windows 型を使用しています。 msodbcsql.hSQL Server構造をpshpack8.hとpoppack.hで包み込んでいます。 windows.hがないと、SDKヘッダー自体の内部でビルドが失敗します。

SDKファイルがインストールされている場所

Platform msodbcsql.h 一括コピーライブラリ
Windows %ProgramFiles%\Microsoft SQL Server\Client SDK\ODBC\180\SDK\Include %ProgramFiles%\Microsoft SQL Server\Client SDK\ODBC\180\SDK\Lib\<architecture>\msodbcsql18.lib
Linux /opt/microsoft/msodbcsql18/include /opt/microsoft/msodbcsql18/lib64、/usr/lib/libmsodbcsql-18.so シンボリック リンク付き
macOS $(brew --prefix msodbcsql18)/include/msodbcsql18 $(brew --prefix)/lib/libmsodbcsql.18.dylib

Windowsでは、Libフォルダには、インストーラーがマシンに配置した各プロセッサアーキテクチャ(x64、x86、arm64など)のサブフォルダが入っています。 Includeフォルダをコンパイラのincludeパスに追加し、architectureサブフォルダをリンカーのライブラリパスに追加します。

Linuxでは、共有オブジェクトはバージョン管理され、 libmsodbcsql-18.6.so.2.1の名前を持ち、 SONAMEを持ちません。 パッケージは、それを指す/usr/lib/libmsodbcsql-18.soをインストールするため、-lmsodbcsql-18オプションなしで-Lを解決できます。 バージョン指定ファイル名を付けるのではなく、そのシンムリンク経由でリンクすれば、ドライバーアップデートでビルドが壊れません。

macOSではHomebrewは独自のプレフィックスにインストールされ、Appleシリコンでは /opt/homebrew 、Intelでは /usr/local です。 両方のプレフィックスはバージョン管理されたCellarディレクトリへのシンムリンクです。 ビルドスクリプトで brew --prefix msodbcsql18 と brew --prefix unixodbc を使い、どちらかをハードコーディングしないでください。

経路の番号は主要ドライバーのバージョンを追跡しています。 バージョン 17 は、Windows では ...\ODBC\170\SDK\ に、Linux では /opt/microsoft/msodbcsql17/ にインストールされ、インポート ライブラリは msodbcsql17.lib です。

プラットフォームごとの完全なファイルインベントリについては、「システム要件、インストール、ドライバーファイル(Windows)」、「LinuxにODBCドライバーをインストールし、macOSでODBCドライバーをインストールしてください」をご覧ください。

ビルド設定を確認してください

このプログラムはヘッダーに対してコンパイルし、ドライバーマネージャーにリンクし、ドライバーマネージャーが見ることができるドライバーを一覧化します。 接続できないので、ビルドや登録の問題とネットワークや認証情報の問題を分けてしまいます。

#include <stdio.h>
#include <wchar.h>

#ifdef _WIN32
#include <windows.h>
#endif

#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>
#include <msodbcsql.h>

static void PrintDiagnostics(SQLSMALLINT handleType, SQLHANDLE handle)
{
    SQLCHAR state[6];
    SQLINTEGER native;
    SQLCHAR message[SQL_MAX_MESSAGE_LENGTH];
    SQLSMALLINT length;

    for (SQLSMALLINT record = 1;
         SQL_SUCCEEDED(SQLGetDiagRec(handleType, handle, record, state, &native,
                                     message, sizeof(message), &length));
         ++record)
    {
        fprintf(stderr, "  [%s] (%ld) %s\n", state, (long)native, message);
    }
}

int main(void)
{
    SQLHENV environment = SQL_NULL_HENV;
    SQLRETURN rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &environment);

    if (!SQL_SUCCEEDED(rc))
    {
        fprintf(stderr, "SQLAllocHandle for the environment failed.\n");
        return 1;
    }

    rc = SQLSetEnvAttr(environment, SQL_ATTR_ODBC_VERSION,
                       (SQLPOINTER)SQL_OV_ODBC3_80, 0);
    if (!SQL_SUCCEEDED(rc))
    {
        fprintf(stderr, "SQLSetEnvAttr for SQL_OV_ODBC3_80 failed.\n");
        PrintDiagnostics(SQL_HANDLE_ENV, environment);
        SQLFreeHandle(SQL_HANDLE_ENV, environment);
        return 1;
    }

    printf("Driver name from msodbcsql.h: %s\n", SQLODBC_DRIVER_NAME);
    printf("Installed drivers:\n");

    SQLCHAR description[256];
    SQLSMALLINT descriptionLength = 0;
    SQLUSMALLINT direction = SQL_FETCH_FIRST;

    while (SQL_SUCCEEDED(SQLDrivers(environment, direction,
                                    description, sizeof(description), &descriptionLength,
                                    NULL, 0, NULL)))
    {
        printf("  %s\n", description);
        direction = SQL_FETCH_NEXT;
    }

    SQLFreeHandle(SQL_HANDLE_ENV, environment);
    return 0;
}

狭いキャラクタープログラムとして構築してください。 SQLODBC_DRIVER_NAME は、UNICODE または _UNICODE が定義されているとワイド文字列に展開されますが、printf を指定した %s では受け取れません。

cl /W4 /I "%ProgramFiles%\Microsoft SQL Server\Client SDK\ODBC\180\SDK\Include" odbc-build-check.c /link odbc32.lib

Windowsでは、/W4がsqlext.hのWindows SDKコピーから2件のC4201: nonstandard extension used: nameless struct/union警告を報告しています。 これらの警告はコードではなくSDKヘッダーから出ており、ビルドは成功します。

最初の行は、バイナリにまとめられたドライバー名を報告します。 残りはドライバーマネージャー自身のリストなので、表示されるはずのドライバーが表示されない場合は、ビルドの問題ではなく登録上の問題です。 あなたのリストは異なり、SQL Serverのドライバーだけでなく、インストールされているすべてのODBCドライバーが含まれています。

Driver name from msodbcsql.h: ODBC Driver 18 for SQL Server
Installed drivers:
  SQL Server
  ODBC Driver 17 for SQL Server
  ODBC Driver 18 for SQL Server
  Microsoft Access Driver (*.mdb, *.accdb)
  Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)
  Microsoft Access Text Driver (*.txt, *.csv)
  Microsoft Access dBASE Driver (*.dbf, *.ndx, *.mdx)

文字列からではなく、SQLODBC_DRIVER_NAMEから接続文字列を構築しましょう。 マクロはコンパイルしたヘッダーを追跡するため、SDKをアップグレードするとドライバー名が一箇所で更新されます。

msodbcsql.hがODBC APIに追加していること

msodbcsql.h標準的なODBC APIをSQL Serverの特有要素で拡張します。 各族は基底定数から数えられた連続した数値範囲を占めます。 範囲はファミリー間で一意ではないので、値を渡す関数がそれらを区別します。

ファミリ 基底定数 Value
SQLSetConnectAttr の接続属性 SQL_COPT_SS_BASE 1200
SQLSetStmtAttr のステートメント属性 SQL_SOPT_SS_BASE 1225
SQLColAttribute の列属性 SQL_CA_SS_BASE 1200
SQLGetInfo の情報タイプ SQL_INFO_SS_FIRST 1199
SQLGetDiagField の診断フィールド SQL_DIAG_SS_BASE -1150
診断用の動的な機能コード SQL_DIAG_DFC_SS_BASE -200

ヘッダーはまた次のように宣言しています:

  • SQL_COPT_SS_AUTHENTICATIONやSQL_COPT_SS_ACCESS_TOKENなどの認証属性は、Microsoft Entra ID設定やアクセストークンを保持します。
  • -150 ~ -199 の範囲の SQL 型識別子。これは、ODBC で定義されていない SQL Server 型 (SQL_SS_VARIANT、SQL_SS_UDT、SQL_SS_XML、SQL_SS_TABLE、SQL_SS_TIME2、SQL_SS_TIMESTAMPOFFSET、SQL_SS_VECTOR) に対するものです。 これらはSQL型を名付けるため、ODBCがSQL型を期待するところに渡すようにします。例えば、SQLBindParameterのParameterType引数などです。
  • バッファ側には3つの一致する C 型があります: SQL_C_SS_TIME2、 SQL_C_SS_TIMESTAMPOFFSET、 SQL_C_SS_VECTOR。 他のSQL Server型はSQL_C_BINARYやSQL_C_WCHARなどの標準的なODBC C型に結合するため、SQL_C_SS_*対応するものはありません。
  • SQL_C_SS_*型が結合する構造は、SQL_SS_TIME2_STRUCT、SQL_SS_TIMESTAMPOFFSET_STRUCT、SQL_SS_VECTOR_STRUCTです。
  • bcp_init、bcp_bind、bcp_sendrow、bcp_batch、bcp_doneを含むプロトタイプやマクロをまとめてコピーします。 BCP_ENCRYPT_OFF、BCP_ENCRYPT_ON、BCP_ENCRYPT_STRICTのオプションはWindowsヘッダーにのみ記載されています。

各プラットフォームは独自の msodbcsql.hを出荷しており、すべてが同じシンボルを宣言しているわけではありません。 SQLPERF構造や、それを埋めるパフォーマンス接続属性(SQL_COPT_SS_PERF_DATAやSQL_COPT_SS_PERF_QUERYなど)は、Windowsそのヘッダーのみに記載されています。 LinuxやmacOSのヘッダーには宣言されておらず、ドライバーもこれらのプラットフォームでパフォーマンスデータを収集しません。 プログラミング ガイドライン(LinuxおよびmacOS)を参照してください。

これらの属性に対応する接続文字列キーワードについては、DSNおよび接続文字列キーワードおよび属性を参照してください。 Microsoft Entra IDの設定については、「Microsoft Entra IDをODBCドライバーで使用」をご覧ください。 ベクトル型については、ベクターデータ型を参照してください。

非同期実行とスレッドのどちらかを選ぶ

一部のODBC関数は同期または非同期で動作します。 同期モードでは、ドライバーはサーバーからの応答まで制御を返しません。 非同期モードでは、ドライバーはすぐに SQL_STILL_EXECUTING を返し、アプリケーションは同じ引数で同じ呼び出しを繰り返し、異なる返却コードが出るまで繰り返します。 SQL_ERRORを含む他のリターンコードがあれば、操作完了を示します。

非同期モードには2つの形態があり、そのうちの1つを使用します。 ドライバーがどれをサポートしているかを確認するには、SQLGetInfo を指定して SQL_ASYNC_MODE を呼び出します。 ドライバがステートメントごとの制御をサポートしている場合はSQL_AM_STATEMENT、設定が接続全体に適用される場合はSQL_AM_CONNECTION、またはドライバが関数を非同期でまったく実行しない場合はSQL_AM_NONEを返します。

ステートメント形式では、1 つのステートメント ハンドルに対して非同期モードを有効にします。 接続上の他の文はすべて同期的に処理されるため、両方の文を同時に実行できます:

SQLSetStmtAttr(hStmt, SQL_ATTR_ASYNC_ENABLE,
               (SQLPOINTER)SQL_ASYNC_ENABLE_ON, SQL_IS_INTEGER);

SQL_ASYNC_MODE SQL_AM_CONNECTION返された場合、文属性は読み取りのみとなり、この呼び出しはSQLSTATE HYC00でSQL_ERROR返します。 代わりに接続フォームを使ってください。

その接続では、以後割り当てるすべてのステートメント ハンドルに対して非同期モードが有効になります。 それがすでに存在するハンドルにも影響するかどうかはドライバー依存なので、ステートメントを割り当てる前に設定してください:

SQLSetConnectAttr(hDbc, SQL_ATTR_ASYNC_ENABLE,
                  (SQLPOINTER)SQL_ASYNC_ENABLE_ON, SQL_IS_INTEGER);

その接続のステートメントで関数がまだ非同期で実行中である場合、呼び出しは SQLSTATE HY010 とともに SQL_ERROR を返します。 開いたカーソルだけでは通話がブロックされません。 SQL_ASYNC_ENABLE_OFFを渡すことで、接続上のすべての文が同期モードに戻されます。

1つの接続でドライバーが同時にサポートする非同期文の数を調べるには、SQL_MAX_ASYNC_CONCURRENT_STATEMENTSで呼びSQLGetInfoしてください。 Microsoft ODBC Driver 18 for SQL Serverは1を返すため、接続ごとに未完成の非同期操作を1つだけ計画し、さらに多くの接続を開くか、それ以上のスレッドを使うようにしましょう。 非 同期実行(ポーリング方式)を参照してください。

スレッドは複数の操作を継続させるもう一つの方法です。 ODBCはマルチスレッドOS上のドライバーがスレッドセーフであることを要求しており、スレッドが他のスレッドが動作を続ける間、ブロッキングODBCコールを行うことができます。 これにより、非同期モードに必要なポーリングループや繰り返しの関数呼び出しを回避できます。 各スレッドに独自のステートメントハンドルを与えてください。 ドライバは同じハンドルを同時に使う2つのスレッドをシリアライズすることが多いため、1つを共有すると並行性が失われます。 マルチスレッディングを参照してください。 新しいコードにはスレッドを優先し、すでに動作している非同期コードを変換する前に自分の作業量を測ってください。

Windows では、ドライバー マネージャーは通知方式にも対応しており、ポーリング ループが不要になります。 Win32イベントを接続やステートメントハンドルに関連付けます。 関数は依然としてすぐに SQL_STILL_EXECUTING に戻り、操作完了時にドライバーマネージャーがイベントを通知します。 このモードでポーリングは無効化されており、元の関数を再度呼び出してもSQLSTATE IM017で返SQL_ERRORされます。 代わりに SQLCompleteAsync に連絡して結果を取り出してください。 これはドライバーマネージャーのバージョンODBC 3.81以降のバージョンが必要で、ドライバーもサポートしなければなりません。 SQLGetInfo SQL_ASYNC_NOTIFICATIONに連絡して確認してください。 返ってくる値は、アプリケーションが宣言するODBCバージョンによって異なります。SQL Server Microsoft ODBC Driver 18の場合、SQL_ATTR_ODBC_VERSIONをSQL_OV_ODBC3_80に設定したアプリケーションはSQL_ASYNC_NOTIFICATION_CAPABLEを受け取り、SQL_OV_ODBC3を宣言したアプリケーションは同じドライバからSQL_ASYNC_NOTIFICATION_NOT_CAPABLEを受け取ります。 接続を割り当てる前に、SQL_OV_ODBC3_80 を宣言してください。 非 同期実行(通知方式) および 通知方法のサンプルを参照してください。

未解決の作戦を中止する

SQLCancel 文ハンドル上でまだ実行中の操作をキャンセルします。 別のスレッドから、またはポーリングループから呼び出し、未処理の呼び出しのハンドルを渡します。

そのためだけ SQLCancel 使ってください。 もう読みたくない結果セットを放棄する場合は、 SQLCloseCursor や SQLMoreResults に電話してください。

sqlncli.h から msodbcsql.h への移行

SQL Server Native Clientは廃止されているため、それを使うアプリケーションはMicrosoft ODBCドライバ for SQL Serverに移行すべきです。 APIは同じODBC APIなので、ほとんどの作業はビルド入力と接続文字列内のドライバー名の変更に関わっています。

SQL Server ネイティブクライアント Microsoft ODBC Driver 18 for SQL Server
sqlncli.h msodbcsql.h
sqlncli11.lib msodbcsql18.lib
sqlncli11.dll msodbcsql18.dll
Driver={SQL Server Native Client 11.0} Driver={ODBC Driver 18 for SQL Server}
SQLNCLI_VER SQLODBC_VER

msodbcsql.hヘッダーはマクロのSQLNCLI_*名を定義しているので、それを使うソースコードはコンパイルを続けます。 これらの定義は #ifndef __sqlncli_h__によって守られており、両方のヘッダーを同じ翻訳ユニットに含めることはできません。 sqlncli.h include を削除してください。

2つのことは引き継がれません。

  • リンクされたサーバーのリストやそのカタログを返す分散型クエリメタデータAPI関数は、 msodbcsql.hで宣言されていません。 それらはSQL Server Native Client専用のものでした。
  • バージョン18はデフォルトで接続を暗号化し、サーバー証明書を検証します。 ネイティブクライアントはそうではありませんでした。 ネイティブ クライアントで動作した接続文字列でも、証明書の信頼設定を修正するか、Encrypt を明示的に設定するまで、最初の接続時に失敗することがあります。 詳細は 「接続暗号化のトラブルシューティング」を参照してください。

バージョン17からバージョン18へのその他の変更については 、メジャーバージョンの違いを参照してください。