Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9370

C#でMySQLを使う - 3.INSERT追加・UPDATE更新・DELETE削除してみる

$
0
0

前提と準備

C#の記事

前回はVisual Studio 2019にMySQL Connectors .NETを用いて、とりあえずMySQLに接続して、SELECTを用いてデータの内容を画面に表示しました。今回はDBのデータそのものを変更を施します(˶ ・ᴗ・ )੭

環境

  • OS:Windows 10 Pro
  • 開発環境:Visual Studio 2019 (MySQL Connectors .NET利用)
  • データベース:MySQL 5.7

MySQLサーバー

テスト用ユーザー:test (パスワード:test1)
データベース:manutest
テーブル名:testtb

idnamememo
INTVARCHAR(64)VARCHAR(256)
必須属性PRIMARY KEYNOT NULL初期値NULL
その他属性AUTO_INCREMENT--

前提

前回のように、Visual Studio 2019とMySQLをインストールし、かつMySQL Connectors .NETがインストールされていること(Visual Studioは自動でMySQL Connectorsのライブラリを認識してくれる)

作業手順

Visual Studio 2019でのコーディング

コンポーネント・コントロールの配置

今回はボタンを押下→MySQLでデータを拾ってくる→画面に表示
これに加えて、名前とメモを入力し、追加や更新などができるようにフォームを追加
右上のリストボックスを選択すると該当するIDが画面表示されるので、選択している際に該当IDの更新や削除ができるようになりますが、細かいUI制御までは触れません

WindowsのC#フォームのプロジェクトを新規作成し、Form1.csデフォルトで開きました

フォームへのコンポーネント配置

  • 左上:データグリッド dataGridView1
  • 右上:リストボックス2つ listBox1・listBox2
    • 選択するとテキストボックス「idNum」に該当するIDを表示する
  • 左下:SQLを読み込むボタン button1
  • 右中央:名前入力 textBoxName・メモ入力 textBoxMemo
  • 右下:選択中のID idNum・新規追加SQL実行 buttonAdd・更新SQL実行 buttonEdit・削除SQL実行 buttonDel

これらを貼り付けます。
データグリッドとリストボックスはSQLのデータを表示させるために配置しました

MySQL Connector .NETの参照を追加

MySQLインストール時と同じように、参照を追加していきます。

MySql.Data

「アセンブリ」の中に実際自動で認識してくれるので、参照マネージャーで、右上の検索画面に「mysql」を入力すると、↑の画面のように「MySql.Data」が何行も出てくるので、とりあえず1つだけ、どれでもいいので選択して(行左にマウスを当てると出てくるチェックボックスをON)「OK」を選択すると…

MySQLを使う

MySql.Data」が追加されました(*˘꒳˘*)
この中にMySQLを扱うC#オブジェクトが入っているのです。

ボタンクリック時のソースを記述する

今回も簡単のため、SQLの実行はボタンクリックで読み込むだけで、Form1.csのクリックイベント動作のみをコーディングしました。本来は規模が大きくなることがほとんどなので、formのボタンクリックではなく、独立したクラスに分けるケースがほとんどですが。。。

Form1.cs サンプルコード
Form1.cs
usingSystem;usingSystem.Collections.Generic;usingSystem.Data;usingSystem.Windows.Forms;usingMySql.Data.MySqlClient;namespaceMySqlFormsTest{publicpartialclassForm1:Form{// 取得したデータのID一覧(フォーム内部変数)privateList<int>idNums;// 選択中のIDprivateintselId;// MySQL接続情報privatestringconnStr="server=127.0.0.1;user id=test;password=test1;database=manutest";publicForm1(){InitializeComponent();}/**
         * 接続ボタン(MySQLサーバーに接続し、一覧データを取得する)
         * */privatevoidbutton1_Click(objectsender,EventArgse){MySqlConnectionconn=newMySqlConnection(this.connStr);// 画面と内部変数を初期化listBox1.Items.Clear();listBox2.Items.Clear();this.idNums=newList<int>();selId=-1;idNum.Text="";buttonEdit.Enabled=false;buttonDel.Enabled=false;try{// 接続を開くconn.Open();// データを取得するテーブルDataTabletbl=newDataTable();// SQLを実行するMySqlDataAdapterdataAdp=newMySqlDataAdapter("SELECT id, name, memo FROM testtb",conn);dataAdp.Fill(tbl);// dataGridViewに表示させるdataGridView1.DataSource=tbl;// 実行結果を1行ずつ参照する場合for(inti=0;i<tbl.Rows.Count;i++){DataRowrow=tbl.Rows[i];// データ行// 右のリストボックスにアイテムを追加listBox1.Items.Add(row[1]);listBox2.Items.Add(row[2]);// 同時にIDを内部変数に追加this.idNums.Add((int)row[0]);}// 接続を閉じるconn.Close();}catch(MySqlExceptionmse){MessageBox.Show(mse.Message,"データ取得エラー",MessageBoxButtons.OK,MessageBoxIcon.Error);}}/**
         * リストボックスの行を選択
         */privatevoidlistBox1_SelectedIndexChanged(objectsender,EventArgse){this.listBox_SelectedIndexChanged(sender,e);// 選択したIDを画面表示if(listBox1.SelectedIndex!=-1){this.selId=idNums[listBox1.SelectedIndex];idNum.Text=idNums[listBox1.SelectedIndex].ToString();}else{this.selId=-1;idNum.Text="";}}privatevoidlistBox2_SelectedIndexChanged(objectsender,EventArgse){this.listBox_SelectedIndexChanged(sender,e);// 選択したIDを画面表示if(listBox2.SelectedIndex!=-1){this.selId=idNums[listBox2.SelectedIndex];idNum.Text=idNums[listBox2.SelectedIndex].ToString();}else{this.selId=-1;idNum.Text="";}}privatevoidlistBox_SelectedIndexChanged(objectsender,EventArgse){// どちらかを選択していないと追加と削除が使えないif(listBox1.SelectedIndex!=-1||listBox2.SelectedIndex!=-1){buttonEdit.Enabled=true;buttonDel.Enabled=true;}else{buttonEdit.Enabled=false;buttonDel.Enabled=false;}}/**
         * 新規追加ボタンを選択
         */privatevoidbuttonAdd_Click(objectsender,EventArgse){MySqlConnectionconn=newMySqlConnection(this.connStr);MySqlTransactiontrans=null;// 実行トランザクション// 新規追加のSQLコマンドstringsqlCmd=@"INSERT INTO testtb (name, memo) VALUES (@name, @memo)";// 追加クエリの開始MySqlCommandcmd=newMySqlCommand(sqlCmd,conn);try{// ステークホルダーのセットcmd.Parameters.AddWithValue("name",textBoxName.Text);cmd.Parameters.AddWithValue("memo",textBoxMemo.Text);cmd.Connection.Open();// 接続を開く// トランザクション監視開始trans=cmd.Connection.BeginTransaction(IsolationLevel.ReadCommitted);// SQL実行cmd.ExecuteNonQuery();// DBをコミットtrans.Commit();}catch(MySqlExceptionmse){trans.Rollback();// 例外発生時はロールバックMessageBox.Show(mse.Message,"データ追加エラー",MessageBoxButtons.OK,MessageBoxIcon.Error);}finally{// 接続はクローズするcmd.Connection.Close();}}/**
         * 編集ボタンを選択
         */privatevoidbuttonEdit_Click(objectsender,EventArgse){MySqlConnectionconn=newMySqlConnection(this.connStr);MySqlTransactiontrans=null;// 実行トランザクション// 編集のSQLコマンドstringsqlCmd=@"UPDATE testtb SET name = @name, memo = @memo WHERE id = @id";// 編集クエリの開始MySqlCommandcmd=newMySqlCommand(sqlCmd,conn);try{// 選択中のIDを用いて、ステークホルダーのセットcmd.Parameters.AddWithValue("id",this.selId);cmd.Parameters.AddWithValue("name",textBoxName.Text);cmd.Parameters.AddWithValue("memo",textBoxMemo.Text);cmd.Connection.Open();// 接続を開く// トランザクション監視開始trans=cmd.Connection.BeginTransaction(IsolationLevel.ReadCommitted);// SQL実行cmd.ExecuteNonQuery();// DBをコミットtrans.Commit();}catch(MySqlExceptionmse){trans.Rollback();// 例外発生時はロールバックMessageBox.Show(mse.Message,"データ更新エラー",MessageBoxButtons.OK,MessageBoxIcon.Error);}finally{// 接続はクローズするcmd.Connection.Close();}}/**
         * 削除ボタンを選択
         */privatevoidbuttonDel_Click(objectsender,EventArgse){MySqlConnectionconn=newMySqlConnection(this.connStr);MySqlTransactiontrans=null;// 実行トランザクション// 削除のSQLコマンドstringsqlCmd=@"DELETE FROM testtb WHERE id = @id";// 削除クエリの開始MySqlCommandcmd=newMySqlCommand(sqlCmd,conn);try{// 選択中のIDを用いて、ステークホルダーのセットcmd.Parameters.AddWithValue("id",this.selId);cmd.Connection.Open();// 接続を開く// トランザクション監視開始trans=cmd.Connection.BeginTransaction(IsolationLevel.ReadCommitted);// SQL実行cmd.ExecuteNonQuery();// DBをコミットtrans.Commit();}catch(MySqlExceptionmse){trans.Rollback();// 例外発生時はロールバックMessageBox.Show(mse.Message,"データ削除エラー",MessageBoxButtons.OK,MessageBoxIcon.Error);}finally{// 接続はクローズするcmd.Connection.Close();}}}}

まずフォームのC#ソースの内部変数として、MySQLのデータでどのIDを取得したかと、右上のリストボックスの項目に対応するIDはどれを選択しているのかを把握するため、Form1にprivate変数を追加しました

// 取得したデータのID一覧(フォーム内部変数)privateList<int>idNums;// 選択中のIDprivateintselId;

読み込むSQLを実行するボタンで「SELECT id, name, memo~」をbutton1_Click()内で実行していると思いますが、単に右上のリストボックスにピックアップするだけでなく、対応するIDを内部変数idNumsで受け持つコードも実装しました

// 実行結果を1行ずつ参照する場合for(inti=0;i<tbl.Rows.Count;i++){DataRowrow=tbl.Rows[i];// データ行// 右のリストボックスにアイテムを追加listBox1.Items.Add(row[1]);listBox2.Items.Add(row[2]);// 同時にIDを内部変数に追加this.idNums.Add((int)row[0]);}

row[0]が取得したデータのID番号ですが、そのままListにAdd()を実行するとObjectを暗黙的に変換できないエラーとなるため、(int)でキャストしました。

listBox1.SelectedIndexlistBox2.SelectedIndex

listBox1_SelectedIndexChanged()などで使っていますが、リストボックスの選択したインデックス番号(0で始まるもの)はこれを使っています(未選択の場合は-1)。選択するとidNumの選択中IDのフィールドに表示する仕組みを入れたんです。選択中のIDは内部変数に入れています。

this.selId=idNums[listBox1.SelectedIndex];

INSERTやUPDATEなどDBの内容を更新するSQLは、MySqlCommandを使ったんですが、こっちのほうがプレースホルダーが使いやすいので、SELECT以外はMySqlCommandを使いました。

stringsqlCmd=@"INSERT INTO testtb (name, memo) VALUES (@name, @memo)";MySqlCommandcmd=newMySqlCommand(sqlCmd,conn);

そして更新の際はトランザクションを使っています。例外が発生したときはいつもロールバックするようにしていますが、正直タイミングは考えるのは大変なので、今回は簡単で例外キャッチのみで;;

try{trans=cmd.Connection.BeginTransaction(IsolationLevel.ReadCommitted);cmd.ExecuteNonQuery();trans.Commit();}catch(MySqlExceptionmse){trans.Rollback();// 例外発生時はロールバック}

実行結果

今回は追加などのボタンに再読み込み機能がないので、追加などのボタンを押した後は「読み込み」ボタンを押して再表示させています(面倒ですが…)

最初に下の画像のようなデータがあるとして、IDが6のデータを更新すると…
編集
編集
「更新」→「読み込み」で、更新に成功しました(˶ ・ᴗ・ )੭

次はIDが5の「Testing」というデータを選択して消してみます
削除
削除
再度読み込みボタンを押して、これも削除成功しました!!

最後に追加してみます
追加
追加
見事成功しました(˶ ・ᴗ・ )੭!!

次回

Visual StudioでMySQLのデータがNULLの場合にハマったことがあるので、そっちについて追ってみます

参考文献

  1. 【Visual Studio】C#からMySqlの使い方 接続するには?SQL文を実行するには? - 困ったー
  2. C#でMySQLからSELECTした結果を取り出したい

関連文献

  1. C#のMySQLでトランザクション使用する / C#でのトランザクションの実装について
  2. Symfoware Server アプリケーション開発ガイド(埋込みSQL編) - FUJITSU - / SQLのトランザクションとは何かの理解
  3. 【MySQL 5.1向けのもの】MySqlTransaction の使用 / C#でのトランザクション実装例
  4. IsolationLevel 列挙型 / C#でのトランザクションレベル - .NET API

Viewing all articles
Browse latest Browse all 9370

Latest Images

Trending Articles