Visual Basic(VB.NET)からMySQLに接続し、ローカルのファイルをテーブルに取り込む

# この記事で分かる事
- VisualStudioのVisual BasicプロジェクトでMySQLへ接続する方法
- ローカルにあるファイルをMySQLのテーブルへ取り込む方法

※備忘録を目的に投稿しております。分かりにくい表現等あるかもしれませんがご了承願います。

# 環境
- VisualStudio : Community 2019 (16.1.1)
- MySQL : 8.0.16 (Dockerコンテナで運用)
- プロジェクト種別 : Visual Basicのコンソールアプリ(.NET Framework)

※Visual BasicとMySQLはそれぞれ別のサーバで稼働しており、Visual Basic側を「ローカル」を呼称しています。

# 手順

## パッケージインストール
VisualStudioのNuGetパッケージマネージャで「MySql.Data」をインストールします。
後は下記のサンプルのように記載するだけで基本的なSQLは発行する事が出来ますが、ファイル取込の場合はいくつか設定が必要です。

## 通常のDB操作の場合(DML、DDL文)

下記のようなコードを記載するだけでOKです。

```visualbasic:sample.vb
Imports MySql.Data.MySqlClient

Const DB_Source as String = "192.168.0.1"
Const DB_Port as String = "3306"
Const DB_Name as String = "dbname"
Const DB_Id as String = "user"
Const DB_Pw as String = "password"

Sub main()
    Using Conn As New MySqlConnection("Database=" + DB_Name _
                                    + ";Data Source=" + DB_Source _
                                    + ";Port=" + DB_Port _
                                    + ";User Id=" + DB_Id _
                                    + ";Password=" + DB_Pw _
                                    + ";sqlservermode=True;")
        Conn.Open()
        Dim query = "INSERT INTO TABLE_NAME VALUES (xxx,uuu,hoge,fuga,aaa)"
        Dim cmd As MySqlCommand = New MySqlCommand(query, Conn)
        cmd.ExecuteNonQuery()
    Conn.Close()
End Sub
```

## ファイル取込の場合

### my.cnfの編集
MySQL側の設定を変更し、サーバを再起動します。

```cnf:my.cnf
[mysqld]

local_infile=1               # ローカルファイルの利用に必須なオプションです。
secure-file-priv=""          # パスを指定すると、そのパスのファイルのみ扱える。今回は空文字指定で全パスを扱えるように指定
net_read_timeout=99999       # 扱うファイルの容量に応じて、必要であれば変更
net_write_timeout=99999      # 扱うファイルの容量に応じて、必要であれば変更
max_allowed_packet=999999999 # 扱うファイルの容量に応じて、必要であれば変更
```
### コードを記載
上記の設定が上手く出来ていれば、ファイル取込が可能になります。
ローカルファイルの取込には「LOAD DATA LOCAL INFILE」文を使用します。

```visualbasic:sample.vb
Imports MySql.Data.MySqlClient

Const DB_Source as String = "192.168.0.1"
Const DB_Port as String = "3306"
Const DB_Name as String = "dbname"
Const DB_Id as String = "user"
Const DB_Pw as String = "password"

Sub main()
    Using Conn As New MySqlConnection("Database=" + DB_Name _
                                    + ";Data Source=" + DB_Source _
                                    + ";Port=" + DB_Port _
                                    + ";User Id=" + DB_Id _
                                    + ";Password=" + DB_Pw _
                                    + ";sqlservermode=True;")
        Conn.Open()
        Dim query = "LOAD DATA LOCAL INFILE 'FILE_PATH' INTO TABLE TABLE_NAME " _  '「FILE_PATH」にファイルパスを指定
                  + "FIELDS TERMINATED BY ',' " _                                  ' 区切り文字に「,」を指定
                  + "LINES TERMINATED BY '\r\n' " _                                ' 改行文字に「CrLf」を指定
                  + "IGNORE 1 LINES"                                               ' ヘッダ行は無視
        Dim cmd As MySqlCommand = New MySqlCommand(query, Conn)
        cmd.ExecuteNonQuery()
    Conn.Close()
End Sub
```

## 参考文献
こちらに「LOAD DATA LOCAL INFILE」文のオプションが詳しく記載してあります。

[第29回　LOAD DATA INFILE構文でテキストファイルからMySQLにデータをロードする](http://gihyo.jp/dev/serial/01/mysql-road-construction-news/0029)