2−4 MySQLのテーブルを更新してみる

 今回は、前回書ききれなかったMySQLのデータベースへの読み書きについて触れてみたい。
 始めに、今回も専用のテーブルを使ってテストをしてみたいので、MySQLの学習から入り、最後はDataAdapterを利用したテーブルの更新で締めくくるようにする。

1.テーブルの定義
 今回は、DBに対する書き込みをする予定なので、項目が2つのテーブルを作成する。
 テーブル名:tentbl (店名テーブル)
 項目1   :tencode (店コード)−主キー
 項目2   :tenname (店名)−可変長文字列

.テーブルの作成
  MYSQL -u hanbai -p
  password
  USE tanpin;
  SET NAMES SJIS;
 以下のように入力してみる。
  CREATE TABLE tentbl
  (
  tencode MEDIUMINT UNSIGNED NOT NULL DEFAULT '0',
  tenname VARCHAR(20),
  PRYMARY KEY(tencode)
  );
 作成されたテーブルをPHPMyAdminで確認した。

3.テーブルへのデータ登録
 LOAD DATAコマンドを用い てテーブル用のデータを取り込むのだが、今回はEXCELで2列の表を作成。A列に店番号、B列に店名を入力し、区切りがカンマ形式になるようCSV形式で保存した。
 このファイルを秀丸エディターで開き、UTF-8形式のファイルとしてd:\MySQL\MySQLServer 5.0\data\tanpin\tenmei.txtという名前で保存した。前回も書いておいたが データは「MySQLをインストールしたホルダーの中にあるDATAホルダー、その下にデータベースと同じホルダーが出来ているのでこの配下に保存しなければならない。上に書いたのは私の環境の場合なので、場所は各自で確認してみてください。
 以下のようにコマンドを入力した。
  MYSQL -u hanbai -p
  password
  USE tanpin;
  SET NAMES SJIS;
  LOAD DATA INFILE 'tenmei.txt' INTO TABLE tentbl
  FIELDS TERMINATED BY ',' ENCLOSED BY '"';
 ここで、select * from tentbl;を行ってみるが、何かおかしい。店番号が正しく出てこない。店番号がスペースだったり、2桁の店番号の1桁面が出てこなかったり。一体、どうしてしまったんだろう?
 このデータをPHPMyAdminで 確認すると、内容は問題なく表示される。どこが悪いか判らないまま、2-3で作成したプログラムを手直しし 店番号と、店名を表示させるものにした。実行してみると・・・。
 なんだ?店名の後ろに・が1個くっついているぞ?これは一体何なのだ?

4.データ確認と内容修正
 Windowsの標準テキストの場合 改行コードは2バイトからなっている。これは通常CR・LFと呼ばれていて CRはキャレッジリターン、LFはラインフィードを示す。LOAD DATAコマンドを再度調べてみたところ、何も指定しない場合は、改行コードとしてLFを採用するらしく、CRがデータの一部として取り込まれてしまう事が判明した。この為、Windows標準データを取り込む場合にはLines Terminatedオプションをつけなければならないのである。今回、この考慮が抜けていた為に、データがおかしくなっていたのだ。
 TRUNCATE TABLE tentbl;
 というSQL文を入力して、テーブルの内容を初期化する。
 次に、
  LOAD DATA INFILE 'tenmei.txt' INTO TABLE tentbl
  FIELDS TERMINATED BY ',' ENCLOSED BY '"'
  LINES TERMINATED BY '\r\n';
 を入力。この3行目がポイントだった。この後に、SELECT * FROM tentbl; というSQL文を入力し、データが正しく登録されているのを確認した。

5.Connecter_Netからの接続DataAdpterのテスト画面
 3に示した処理を行い、データが正しく表示されるのを確認した。
 次に、データを更新するわけだが Microsoftの「DB設計者のための明解ADO.NET第1回」が非常に参考になった。毎回、 これにあわせてプログラムを作成してみたので、以下に示してみたい。
 はじめに、Visual Basic 2005 Express Editionを起動し、フォーム中にリストボックスとボタンを二個入れたものを作成した。(一つ目のボタンは3で示したDataReaderによるデータの取得。二つ目のボタンは、DataAdapterを用いたデータの取得用である。)
 具体的なコードを以下に示す。

Imports MySql.Data.MySqlClient

Public Class Form1

    Button1_Clickは省略

 Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim sqlDA As MySql.Data.MySqlClient.MySqlDataAdapter 'データアダプタ作成
Dim resultDS As DataSet 'データセットオブジェクト
Dim I As Integer 'カウンター
Dim MyconString As String 'MySQL接続文字列
'DataAdapterオブジェクトの作成
sqlDA = New MySql.Data.MySqlClient.MySqlDataAdapter
'DataSetオブジェクトの作成
resultDS = New DataSet()
'MySQL接続文字列
MyconString = "server=localhost;user id=hanbai;password=password;database=tanpin;"

With sqlDA
'sqlDAにSelectCommandを追加
.SelectCommand = New MySqlCommand()
With .SelectCommand
.CommandType = CommandType.Text
.CommandText = "select * from tentbl"
.Connection = New MySqlConnection(MyconString)
End With
End With

ListBox1.Items.Clear()
'検索結果をDataSetへ格納
Try
sqlDA.Fill(resultDS, "tentbl")
'これ以降は非接続でのデータアクセス
'Dataset内のテーブル"tentbl"の各レコードに対して処理を実行
For I = 0 To resultDS.Tables("tentbl").Rows.Count - 1
ListBox1.Items.Add(resultDS.Tables("tentbl").Rows(I).Item("tencode").ToString() & " " & _
resultDS.Tables("tentbl").Rows(I).Item("tenname").ToString() & " " & _
Len(resultDS.Tables("tentbl").Rows(I).Item("tenname").ToString()))
Next
Catch ex As Exception
MessageBox.Show(e.ToString)
Finally
End Try
End Sub

 このように入力し、起動。Button2を押す(「DataAdpterテスト」ボタン押し下げ)によって、3と同じ結果が表示されるのを確認した。
 なお、店名の後ろに店名の文字数を表示させている。DataAdpterのテスト

6.Connecter_Netによるデータの更新

  5によって作成した画面に今度はボタンを一個追加、テキストボックスを二個追加する。画面のイメージが悪いので、ボタンの位置とテキストボックスの位置は若干移動させている。
 具体的なコードを以下に示す。

 Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Dim sqlDA As MySql.Data.MySqlClient.MySqlDataAdapter 'データアダプタ作成
Dim sqlCmdBldr As MySqlCommandBuilder 'SQLコマンド作成
Dim resultDS As DataSet 'データセットオブジェクト
Dim MyconString As String 'MySQL接続文字列
'DataAdapterオブジェクトの作成
sqlDA = New MySql.Data.MySqlClient.MySqlDataAdapter
'DataSetオブジェクトの作成
resultDS = New DataSet()
'MySQL接続文字列
MyconString = "server=localhost;user id=hanbai;password=password;database=tanpin;"

With sqlDA
'sqlDAにSelectCommandを追加
.SelectCommand = New MySqlCommand()
With .SelectCommand
.CommandType = CommandType.Text
.CommandText = "select * from tentbl"
.Connection = New MySqlConnection(MyconString)
End With
'検索結果をDataSetへ格納
.Fill(resultDS, "tentbl")
End With
'メインメモリーのDatasetに対する更新処理
resultDS.Tables("tentbl").Rows(Val(TextBox1.Text) - 1).Item("tenname") = TextBox2.Text
Try
'Update文の自動実行のためにCommandBuilderオブジェクトを作成するテーブル更新テスト
sqlCmdBldr = New MySqlCommandBuilder(sqlDA)
'DataSetに対する更新結果をDBに反映
sqlDA.Update(resultDS, "tentbl")
MessageBox.Show("レコードは更新されました")
Catch ex As Exception
MessageBox.Show(e.ToString)
Finally
End Try
End Sub

 テキストボックス1に店番号を、テキストボックスの2に店名を入力し、ボタン3(「データ更新テスト」)を押すと、入力した内容にテーブルが書き換えられ、その後でボタン2を押すと、今度は更新された内容が表示されるというわけだ。

 実際に動かしてみたのが、右に示した画面となる。店番号8番(実際には、上から8番目のデータ)が、最初は神田店だったのが、更新を行った事によって梅田店になっている。

 DataReaderとDataAdapterのとちらを利用しても、読み込む場合には同じ結果が得られている。どちらを使うかは、データ処理を行うケースによって決めれば良い事である。常に接続しておく必要があればDataReaderを使用すべきだし、データの参照が主な業務であれば(排他を考慮に入れ)DataAdapterが望ましい。

「市民の目」トップページへ戻る