2016年10月20日

【C#】SqlDataAdapterによる追加・更新・削除


以前、SqlDataAdapterにより抽出したデータをDataGridViewに表示する方法をご紹介しましたが、今回はDataGridViewに表示したデータを変更したり削除したり、または追加して、それをSQL Serverに反映させる方法をご紹介します。

ちなみに、今回も開発ツールは、Visual Studio Community 2015 を使っています。


まず、フォームにこのようにコントロールを貼り付け、下記のように名前を付けてください。

コントロール 名前
DataGridView dgv
Button buttonView
Button buttonOK
Button buttonCancel
Button buttonApply


ソースは下記のようになります。

C#
using System;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;

namespace SqlDataAdapterTest2
{
    public partial class Form1 : Form
    {
        private SqlConnection Cnn;
        private SqlCommand Cmd;
        private SqlCommand InsCmd;
        private SqlCommand UpdCmd;
        private SqlCommand DelCmd;
        private SqlDataAdapter Dta;
        private SqlTransaction Txn;
        private DataSet Dts = new DataSet();
        bool cancelFlag = false;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string ConnectionString = @"Data Source=localhost\MSSQLSERVER2016;Initial Catalog=TESTDB;Integrated Security=True";

            Cnn = new SqlConnection(ConnectionString);
            Cnn.Open();

            Cmd = new System.Data.SqlClient.SqlCommand();
            InsCmd = new System.Data.SqlClient.SqlCommand();
            UpdCmd = new System.Data.SqlClient.SqlCommand();
            DelCmd = new System.Data.SqlClient.SqlCommand();
            Dta = new System.Data.SqlClient.SqlDataAdapter();

            // 適用ボタン非活性
            this.buttonApply.Enabled = false;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.Validate();

            try
            {
                // キャンセルボタンの場合、保存しないで終了。
                if (cancelFlag == true)
                {
                    return;
                }

                if (Dts.HasChanges())
                {
                    DialogResult result;

                    result = MessageBox.Show("データが変更されています。保存しますか?", "質問", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);

                    switch (result)
                    {
                        case DialogResult.Yes:
                            Apply();
                            break;
                        case DialogResult.No:
                            break;
                        case DialogResult.Cancel:
                            e.Cancel = true;
                            break;
                        default:
                            e.Cancel = true;
                            break;
                    }
                    return;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);  
            }
            finally
            {
                if (Dta != null) Dta.Dispose();
                if (DelCmd != null) DelCmd.Dispose();
                if (UpdCmd != null) UpdCmd.Dispose();
                if (InsCmd != null) InsCmd.Dispose();
                if (Cmd != null) Cmd.Dispose();
                if (Dts != null) Dts.Dispose();
                if (Cnn != null) Cnn.Close();
            }
        }
        private void dgv_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            // セルの値が変更されたら適用ボタンを活性化
            this.buttonApply.Enabled = true;
        }

        private void dgv_UserDeletedRow(object sender, DataGridViewRowEventArgs e)
        {
            // 行削除が行われたら適用ボタンを活性化
            this.buttonApply.Enabled = true;
        }

        private void buttonView_Click(object sender, EventArgs e)
        {
            SetDataSource();
        }

        private void buttonOK_Click(object sender, EventArgs e)
        {
            // OK
            Apply();
            this.Close();
        }

        private void buttonCancel_Click(object sender, EventArgs e)
        {
            // キャンセル
            cancelFlag = true;
            this.Close();
        }

        private void buttonApply_Click(object sender, EventArgs e)
        {
            // 適用
            Apply();
            SetDataSource();  
            this.buttonApply.Enabled = false;
        }

        private void Apply()
        {
            try
            {
                if (Dts.HasChanges())
                {
                    // トランザクションを開始
                    Txn = Cnn.BeginTransaction();

                    Dta.UpdateCommand.Transaction = Txn;
                    Dta.DeleteCommand.Transaction = Txn;
                    Dta.InsertCommand.Transaction = Txn;

                    // データ更新
                    Dta.Update(Dts, "T_Animals");

                    // トランザクションをコミット
                    Txn.Commit();
                }
            }
            catch
            {
                Txn.Rollback();
                throw;
            }
            finally
            {
                if (Txn != null)
                {
                    Txn.Dispose();
                }
            }
        }

        private void SetDataSource()
        {
            try
            {
                // Selectコマンドの作成
                Cmd.Connection = Cnn;
                Cmd.CommandType = CommandType.Text;
                Cmd.CommandText = "SELECT [ID], [Name], [Type] FROM [T_Animals] ORDER BY [ID]";

                // 追加コマンドの作成
                InsCmd.Connection = Cnn;
                InsCmd.CommandType = CommandType.Text;
                InsCmd.CommandText = "INSERT INTO [T_Animals] ([ID], [Name], [Type]) VALUES (@ID, @Name, @Type)";
                InsCmd.Parameters.Clear();
                InsCmd.Parameters.Add("@ID", SqlDbType.Int, 4, "ID");
                InsCmd.Parameters.Add("@Name", SqlDbType.NVarChar, 50, "Name");
                InsCmd.Parameters.Add("@Type", SqlDbType.NVarChar, 50, "Type");

                // 更新コマンドの作成
                UpdCmd.Connection = Cnn;
                UpdCmd.CommandType = CommandType.Text;
                UpdCmd.CommandText = "UPDATE [T_Animals] SET [ID] = @ID, [Name] = @Name, [Type] = @Type WHERE [ID] = @ID"; 
                UpdCmd.Parameters.Clear();
                UpdCmd.Parameters.Add("@ID", SqlDbType.Int, 4, "ID");
                UpdCmd.Parameters.Add("@Name", SqlDbType.NVarChar, 50, "Name");
                UpdCmd.Parameters.Add("@Type", SqlDbType.NVarChar, 50, "Type");

                // 削除コマンドの作成
                DelCmd.Connection = Cnn;
                DelCmd.CommandType = CommandType.Text;
                DelCmd.CommandText = "DELETE FROM [T_Animals] WHERE [ID] = @ID";
                DelCmd.Parameters.Clear();
                DelCmd.Parameters.Add("@ID", SqlDbType.Int, 4, "ID");

                if (Dts.Tables.Contains("T_Animals"))
                {
                    Dts.Tables["T_Animals"].Clear();
                }

                // 各コマンドの設定
                Dta.SelectCommand = Cmd;
                Dta.InsertCommand = InsCmd;
                Dta.UpdateCommand = UpdCmd;
                Dta.DeleteCommand = DelCmd;

                // 抽出したデータをデータセットに格納
                Dta.Fill(Dts, "T_Animals");

                // 列クリア
                this.dgv.Columns.Clear();

                // DataGridViewのデータソースを設定
                this.dgv.DataSource = null;
                this.dgv.DataSource = Dts.Tables["T_Animals"];

                // 適用ボタン非活性
                this.buttonApply.Enabled = false;
            }
            catch
            {
                throw;
            }
        }
    }
}



「OK」または「適用」ボタンで変更した内容がデータベースへ反映されます。

長くなったので、VBのソースはまた次回ご紹介します。


スポンサーリンク