introbotics’s blog

人工知能、機械の心について思いついたことを並べてます

スポンサーリンク

visual stdio c++ からデータベース(localdb)への接続

SQL Serverオブジェクトエクスプローラーで作成したlocalDBに対し、
ODBCを利用してのVisualC++(コンソールアプリケーション)プログラムからの接続手順メモです

使用環境

Visual Stdio 2017 C++
SQL Serverオブジェクトエクスプローラーで作成したlocalDB

手順

Visual Studioでのlocaldbデータベースの作成

Visual Studio インストーラーを起動します。
f:id:clay0:20220305173227p:plain

Visual Studio を選択し、 [変更] を選択します。
ワークロードの一覧で [データの保存と処理] の下にある [SQL Server Data Tools] を選択します。
右下の変更を選択し、インストールします

f:id:clay0:20220305173426p:plain


Visual Studio を起動
[表示] > Visaul StudioからSQL Serverオブジェクトエクスプローラーを表示

LocalDB((localdb)\ProjectsV13 ...)が表示されるのでダブルクリック?で開封し
「データベース」を右クリックして「新しいデータベースの追加」を選択します。
※初回はデータベースを開いた際に多少時間がかかる

f:id:clay0:20220305173619p:plain


データベース名とデータベースを保存するフォルダを指定します。
本記事では database2 という名前のDBを作成しています。
データベースが作成されます

データベースへのデータ入力

作成したデータベースからテーブルを右クリックして「新しいテーブルの追加...」を選択します。
f:id:clay0:20220305173759p:plain

テーブルに入れる値を入れていきます
左上にある更新を押します。
ダイアログが表示されたらデータベースの更新を押します。
f:id:clay0:20220305174215p:plain
f:id:clay0:20220305174315p:plain


作成したデータベース(本記事ではdatabase2)を右クリックして「プロパティ」をクリックします。
下の方に「接続文字列」という欄があるので、文字列をコピペします

f:id:clay0:20220305174701p:plain

控えた文字列
Data Source=(localdb)\ProjectsV13;Initial Catalog=database2;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False

データベース側設定は上記で完了します

DSN (Data Source Name) への登録

・ODBC データ ソース アドミニストレータを起動
※windowsでODBCで検索すると選べる
 64bitを選択

f:id:clay0:20220305175049p:plain

システムDSNのタブで追加を選択
本記事のようにlocalDBに接続する場合は、SQLSERVER Native Client11.0を選択
他のソフトウェアのDBへ接続する場合は、それぞれ対応するツールを選択
f:id:clay0:20220305175122p:plain

下記のように接続先データソース設定を入力
f:id:clay0:20220305175326p:plain

データソース名:任意 本例ではProjectsV13
説明:任意
SQLサーバ名:上記手順の接続文字列で確認したサーバ名を入力 本例では(localdb)\ProjectsV13

次のページで統合Windows認証を使うを選択
その他そのままOKで進めて完了を選択

接続テストで問題なく接続できることを確認
f:id:clay0:20220305175613p:plain

C++でのODBCを利用したDBへの接続

参考URLのほぼ丸パクリですが、ソース張ります。

#include <iostream>
#include <windows.h>

#include <sql.h>	
#include <sqlext.h>	
#include <sqltypes.h>	
#include <sqlucode.h>	
#pragma comment(lib, "odbc32.lib")
using namespace std;

int main()
{
	SQLRETURN res;
	SQLHANDLE	henv = SQL_NULL_HANDLE;
	SQLHDBC		hdbc = SQL_NULL_HANDLE;
	SQLWCHAR	szConnStrOut[1024] = { L'tmpszConnStrOut' };
	SQLSMALLINT cchConnStrOut = 0;
	SQLWCHAR	szState[6] = { L'tmpszState' };
	SQLWCHAR	szErrorMsg[1024] = { L'tmpszErrorMsg' };
	SQLINTEGER  nErrorCode = 0;
	SQLSMALLINT nSize = 0;
	wcout.imbue(std::locale("Japanese"));//wcoutでの日本語出力に必要

	// 環境ハンドルの作成
	res = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
	if (SQL_SUCCEEDED(res)) {
		res = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, reinterpret_cast<SQLPOINTER>(SQL_OV_ODBC3), 0);

		// 接続ハンドルの作成
		res = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
		if (SQL_SUCCEEDED(res)) {
			// データベースへ接続
			res = SQLDriverConnect(hdbc, NULL, (SQLWCHAR*)L"dsn=ProjectsV13;DRIVER={SQL SERVER Native Client 11.0};database=database2;Integrated Security=True;Trusted_Connection=Yes;", SQL_NTS, szConnStrOut, 1024, &cchConnStrOut, SQL_DRIVER_NOPROMPT);
			std::wcout << L"szConnStrOut=[" << szConnStrOut << L']' << std::endl;

			if (SQL_SUCCEEDED(res)) {
				printf("接続成功\n");
				SQLDisconnect(hdbc);
			}
			else {
				SQLGetDiagRec(SQL_HANDLE_DBC, hdbc, 1, szState, &nErrorCode, szErrorMsg, sizeof(szErrorMsg), &nSize);
				std::wcout << L"connect error State=[" << szState << L"] ErrorMsg[" << szErrorMsg << L"]" << std::endl;
			}
			SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
		}
	}
	SQLFreeHandle(SQL_HANDLE_ENV, henv);
	return 0;
}//Main


接続するデータベースを切り替える場合、下記の記述を変更します。
DSN作成時に作成したデータソースをdsn=(データソース名)として指定します。
また、私用するデータベース名も指定します。
接続成功と表示されればひとまずlocaldbへの接続が完了しています。

res = SQLDriverConnect(hdbc, NULL, (SQLWCHAR*)L"dsn=ProjectsV13;DRIVER={SQL SERVER Native Client 11.0};database=database2;Integrated Security=True;Trusted_Connection=Yes;", SQL_NTS, szConnStrOut, 1024, &cchConnStrOut, SQL_DRIVER_NOPROMPT);