C#(コンソール) : ODBC 経由のデータベースの読込み

コンソールから、Windows UI である『ファイル参照ダイアログ』を使用する為に、System.Windows.Forms を参照して [STAThread] を記述しています



概要

ファイル選択をキャンセルした場合は、最初に設定した MySQL に対してアクセスします。ファイル選択で、.xls か .xlsx か .mdb が .accdb を選択すると、それをデータベースとしてアクセスします。
using System;
using System.Data.Odbc;
using System.Diagnostics;
using System.Windows.Forms;

namespace DBAccess
{
	class Program
	{
		[STAThread]
		static void Main(string[] args)
		{
			// データベースアクセスに必要なクラス
			OdbcConnection myCon;
			OdbcCommand myCommand;
			OdbcDataReader myReader;

			// ODBC 接続文字列作成用のクラス
			OdbcConnectionStringBuilder builder = new OdbcConnectionStringBuilder();

			// *******************************************
			// インストールされているドライバ文字列
			// 初期は MySQL として準備する
			// *******************************************
			builder.Driver = "MySQL ODBC 8.0 Unicode Driver";
			// builder.Driver = "MySQL ODBC 5.3 Unicode Driver";

			// 接続用のパラメータを追加
			builder.Add("SERVER", "localhost");
			builder.Add("DATABASE", "lightbox");
			builder.Add("UID", "root");
			builder.Add("PWD", "");

			// 接続文字列の内容を確認
			Console.WriteLine(builder.ConnectionString);

			// System.Windows.Forms の参照が必要です
			OpenFileDialog ofd = new OpenFileDialog();

			// *******************************************
			// ファイル選択した場合はその DB を使用する
			// *******************************************
			ofd.Filter = "AccessとExcel|*.mdb;*.accdb;*.xls;*.xlsx|すべてのファイル(*.*)|*.*";
			ofd.FilterIndex = 1;
			ofd.Title = "データベースを選択してください";
			ofd.RestoreDirectory = true;
			// 選択した場合は再設定する
			if (ofd.ShowDialog() == DialogResult.OK)
			{
				// リセット
				builder.Clear();
				// 拡張子文字列の簡易チェックで Excel か Access が判断する
				if (ofd.FileName.ToLower().IndexOf(".xl") != -1 )
				{
					// インストールされているドライバ文字列
					builder.Driver = "Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)";
				}
				else
				{
					builder.Driver = "Microsoft Access Driver (*.mdb, *.accdb)";
				}

				// 接続用のパラメータを追加
				builder.Add("dbq", ofd.FileName);
			}

			// *******************************************
			// 新しい OdbcConnection オブジェクトを作成
			// ( using で使用後の自動解放を行う )
			// https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/using-statement
			// ※ 接続を持続したい場合は using は使わない
			// *******************************************
			using (myCon = new OdbcConnection())
			{

				// 接続文字列を設定
				myCon.ConnectionString = builder.ConnectionString;

				// 接続処理
				try
				{
					// 接続
					myCon.Open();
				}
				catch (OdbcException ex)
				{
					// エラー内容( パスワード等でテストする )
					Console.WriteLine($"Console : {ex.Message}");
					Debug.WriteLine($"Debug : {ex.Message}");
				}

				// 接続に失敗している場合は終了
				if (myCon.State != System.Data.ConnectionState.Open)
				{
					// 終了前に停止
					Console.ReadLine();
					return;
				}

				// *******************************************
				// 接続が完了したので読み出しの準備
				// ▼ 実行する SQL
				// *******************************************
				string myQuery = "select * from 社員マスタ";

				using (myCommand = new OdbcCommand())
				{
					// 実行する為に必要な情報をセット
					myCommand.CommandText = myQuery;
					myCommand.Connection = myCon;

					// *******************************************
					// 接続と SQL を使用して列データを取り出す
					// https://docs.microsoft.com/ja-jp/dotnet/api/system.data.odbc.odbcdatareader
					// *******************************************
					using (myReader = myCommand.ExecuteReader())
					{

						Console.WriteLine($"定義されている列の数 : {myReader.FieldCount}");

						// *******************************************
						// 列名の一覧
						// *******************************************
						for (int i = 0; i < myReader.FieldCount; i++)
						{
							if (i != 0)
							{
								Console.Write(",");
							}
							Console.Write(myReader.GetName(i));
						}
						// 改行
						Console.WriteLine();

						// *******************************************
						// データ型の一覧
						// *******************************************
						for (int i = 0; i < myReader.FieldCount; i++)
						{
							if (i != 0)
							{
								Console.Write(",");
							}
							Console.Write(myReader.GetDataTypeName(i));
						}
						// 二つの改行 
						Console.WriteLine("\n");


						// *******************************************
						// カンマ区切り( CSV ) で出力
						// *******************************************
						while (myReader.Read())
						{
							// 文字列
							Console.Write($"{GetValue(myReader, "社員コード")},");
							Console.Write($"{GetValue(myReader, "氏名")},");
							Console.Write($"{GetValue(myReader, "フリガナ")},");
							// 整数
							Console.Write($"{GetValue(myReader, "給与")},");
							Console.Write($"{GetValue(myReader, "手当")},");
							// 日付
							Console.Write($"{GetValue(myReader, "作成日").Substring(0, 10)},");
							Console.Write($"{GetValue(myReader, "更新日")},");
							Console.Write(GetValue(myReader, "生年月日"));

							// 改行
							Console.WriteLine();

						}

						myReader.Close();

					}

					// OdbcCommand に Close はありません
				}

				// 接続解除
				myCon.Close();
			}

			// 終了確認用
			Console.WriteLine("\n処理が終了しました");

			// 終了前に停止
			Console.ReadLine();
		}

		// *******************************************
		// データを列名文字列で取り出す関数
		// *******************************************
		static string GetValue(OdbcDataReader myReader, string strName)
		{

			string ret = "";
			int fld = 0;

			// 指定された列名より、テーブル内での定義順序番号を取得
			fld = myReader.GetOrdinal(strName);
			// 定義順序番号より、NULL かどうかをチェック
			if (myReader.IsDBNull(fld))
			{
				ret = "";
			}
			else
			{
				// NULL でなければ内容をオブジェクトとして取りだして文字列化する
				ret = myReader.GetValue(fld).ToString();
			}

			// 列の値を返す
			return ret;

		}
	}
}


関連する記事

32ビット ODBC ドライバの一覧を取得する