質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

3回答

2496閲覧

削除フラグ WHERE句について

ICCI

総合スコア14

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

1クリップ

投稿2019/09/08 16:11

編集2019/09/15 04:28

現在C#で住所録を作成しており、削除フラグを使用して論理削除するという課題に悩んでいます。
テーブルカラムにはDEL_FLG作成済みです。
削除ボタン(DelBtn)をクリックすると確認メッセージ表示後にDataGridViewのその行を削除するという仕様です。
削除ボタンクリックイベント内削除処理の"UPDATE mst_address SET DEL_FLG = 1"のWHERE句の指定の仕方がわからず、現在は削除ボタンをクリックすると全てのデータのDEL_FLGが1になってしまいます。WHERE句で削除ボタンをクリックした行を指定するにはどうしたら良いでしょうか?

テーブルは以下になります。
主キーはSEQ_NOとなっており、非表示の状態です。
一行ごとに削除ボタンがあるDataGridViewで、ボタンを押下した行を削除するという仕様です。
よろしくお願い致します。

SQL

1 2CREATE TABLE `mst_address` ( 3 `SEQ_NO` int(11) NOT NULL AUTO_INCREMENT COMMENT '管理番号', 4 `NAME1` varchar(10) NOT NULL COMMENT '氏名1', 5 `NAME2` varchar(10) NOT NULL COMMENT '氏名2', 6 `ZIP1` varchar(3) NOT NULL COMMENT '郵便番号1', 7 `ZIP2` varchar(4) NOT NULL COMMENT '郵便番号2', 8 `ADDRESS3` varchar(100) NOT NULL COMMENT '住所3', 9 `ADDRESS1` varchar(100) DEFAULT NULL COMMENT '住所1', 10 `ADDRESS2` varchar(100) DEFAULT NULL COMMENT '住所2', 11 `TEL` varchar(20) DEFAULT NULL COMMENT '電話番号', 12 `INS_USER` varchar(10) NOT NULL COMMENT '登録者', 13 `INS_DATETIME` datetime NOT NULL COMMENT '登録日', 14 `UPD_USER` varchar(10) NOT NULL COMMENT '更新者', 15 `UPD_DATETIME` datetime NOT NULL COMMENT '更新日', 16 `DEL_FLG` bit(1) NOT NULL COMMENT '削除フラグ', 17 PRIMARY KEY (`SEQ_NO`) 18) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 19

追記
主キーSEQ_NOを追加(テーブルには非表示)し、WHERE句に指定した修正後ソースコードです。
dataGridView1.CurrentRow.Cells[1].ValueでSEQ_NOの値が取得できることは確認しています。

C#

1namespace AddressList 2{ 3 public partial class AddressList : Form 4 { 5 public AddressList() 6 { 7 InitializeComponent(); 8 } 9 10 public void 住所一覧_Load(object sender, EventArgs e) 11 { 12 // MySQLへの接続 13 using (MySqlCommand command = new MySqlCommand()) 14 { 15 MySqlConnection conn = new MySqlConnection(); 16 conn.ConnectionString = "server=サーバ名; user id=ID; Password=PW; database=address_note"; 17 18 //DBとの接続オープン 19 conn.Open(); 20 21 //データを保存するテーブル作成 22 DataTable dt = new DataTable(); 23 24 //SQL文と接続情報を引数に、データアダプターを作成 25 MySqlDataAdapter da = new MySqlDataAdapter("SELECT **SEQ_NO,** NAME1,NAME2,ZIP1,ZIP2,ADDRESS1,ADDRESS2,ADDRESS3,TEL FROM mst_address WHERE DEL_FLG = 0", conn); 26 27 28 //SQL文で指定したデータをDataTableに格納 29 da.Fill(dt); 30 31 //表示させる 32 dataGridView1.DataSource = dt; 33 34 //DBとの接続クローズ 35 conn.Close(); 36 37 38 ** dataGridView1.Columns[1].Visible = false; //SEQ_NOを非表示にする** 39 //横幅指定・削除ボタン配置 40 dataGridView1.Columns[2].Width = 50; 41 dataGridView1.Columns[3].Width = 45; 42 dataGridView1.Columns[4].Width = 40; 43 dataGridView1.Columns[5].Width = 40; 44 dataGridView1.Columns[6].Width = 70; 45 dataGridView1.Columns[7].Width = 42; 46 dataGridView1.Columns[8].Width = 40; 47 dataGridView1.Columns[9].Width = 90; 48 dataGridView1.Columns["DelBtn"].DisplayIndex = 9; 49 50 //氏名昇順でソートする 51 dataGridView1.Sort(dataGridView1.Columns[2], ListSortDirection.Ascending); 52 } 53 } 54 55 //検索ボタン 56 private void Button1_Click_1(object sender, EventArgs e) 57 { 58 { 59 //テキストボックスの文字取得 60 string prefecture = AddressSrc.Text; 61 string name = NameSrc.Text; 62 63 //未入力で検索押下時 64 if (prefecture == "" && name == "") 65 { 66 MessageBox.Show("氏名または都道府県を入力してください"); 67 } 68 else if (prefecture != "") //都道府県検索 69 { 70 //MySQLへ接続 71 MySqlConnection conn = new MySqlConnection(); 72 conn.ConnectionString = Properties.Settings.Default.address_noteConnectionString; 73 MySqlCommand sqlCommand = new MySqlCommand(@"SELECT **SEQ_NO**, NAME1, NAME2, ZIP1, ZIP2, ADDRESS1, ADDRESS2, ADDRESS3, TEL FROM mst_address WHERE ADDRESS1 = @ADDRESS1 AND DEL_FLG = 0", conn); 74 75 //データを保存するテーブル作成 76 DataTable dt = new DataTable(); 77 78 try 79 { 80 //DBとの接続オープン 81 conn.Open(); 82 83 sqlCommand.Parameters.Add(new MySqlParameter(@"ADDRESS1", prefecture)); 84 85 MySqlDataReader reader = sqlCommand.ExecuteReader(); 86 87 dt.Load(reader); 88 89 dataGridView1.DataSource = dt; 90 91 reader.Close(); 92 } 93 catch 94 { 95 MessageBox.Show("検索エラーです"); 96 } 97 finally 98 { 99 conn.Close(); 100 } 101 } 102 else if (name != "") //氏名検索 103 { 104 //MySQLへ接続 105 MySqlConnection conn = new MySqlConnection(); 106 conn.ConnectionString = Properties.Settings.Default.address_noteConnectionString; 107 MySqlCommand sqlCommand = new MySqlCommand(@"SELECT **SEQ_NO**, NAME1, NAME2, ZIP1, ZIP2, ADDRESS1, ADDRESS2, ADDRESS3, TEL FROM mst_address WHERE NAME1 LIKE @NAME1 AND DEL_FLG = 0", conn); 108 109 //データを保存するテーブル作成 110 DataTable dt = new DataTable(); 111 112 try 113 { 114 //DBとの接続オープン 115 conn.Open(); 116 117 sqlCommand.Parameters.Add(new MySqlParameter(@"NAME1", @"%" + name + @"%")); 118 119 MySqlDataReader reader = sqlCommand.ExecuteReader(); 120 121 dt.Load(reader); 122 123 dataGridView1.DataSource = dt; 124 125 reader.Close(); 126 } 127 catch 128 { 129 MessageBox.Show("検索エラーです"); 130 } 131 finally 132 { 133 conn.Close(); 134 } 135 } 136 } 137 } 138 139 140 // 終了ボタン 141 private void Button2_Click(object sender, EventArgs e) 142 { 143 this.Close(); 144 } 145 146 //削除ボタン 147 private void DataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e) 148 { 149 // 削除ボタンの列かどうかを確認 150 if (e.ColumnIndex == this.dataGridView1.Columns["DelBtn"].Index) 151 { 152 if (DialogResult.Yes == MessageBox.Show("削除してもよろしいですか?", "削除", 153 MessageBoxButtons.YesNo, MessageBoxIcon.Question)) 154 { 155 // 削除 156 //this.dataGridView1.Rows.RemoveAt(e.RowIndex); 157 158 MySqlConnection conn = new MySqlConnection(); 159 conn.ConnectionString = Properties.Settings.Default.address_noteConnectionString; 160 conn.Open(); 161 MySqlCommand sqlCommand = new MySqlCommand("UPDATE mst_address SET DEL_FLG = 1** WHERE SEQ_NO = dataGridView1.CurrentRow.Cells[1].Value**", conn); 162 DataTable dt = new DataTable(); 163 MySqlDataReader reader = sqlCommand.ExecuteReader(); 164 dt.Load(reader); 165 dataGridView1.DataSource = dt; 166 reader.Close(); 167 168 MessageBox.Show("削除完了しました。"); 169 170 } 171 else 172 { 173 this.Close(); 174 } 175 } 176 } 177 } 178} 179 180

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/09/08 22:19

主キーはないのですか? テーブルの構造はどうなっているのですか?
ICCI

2019/09/14 13:12

遅くなりましたが、CREATE TABLEを追記せさせて頂きました。よろしくお願い致します。
guest

回答3

0

mst_addressテーブルの仕様が分からないので
NAME1,NAME2,ZIP1,ZIP2,ADDRESS1,ADDRESS2,ADDRESS3,TEL
のうちキーとなるものがあるのであれば、それを指定すればいいのではないですか?
もしキーがないのでしたら、テーブル仕様としてキーを追加した方がいいと思います。

追記

それであれば、SEQ_NOも読み込み、DataGridView上では非表示にしてください。
そして、WHERE句にSEQ_NOを条件として指定するようにしてください。

投稿2019/09/08 22:10

編集2019/09/14 14:00
YAmaGNZ

総合スコア10222

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ICCI

2019/09/15 04:34

ありがとうございます。SEQ_NOを読み込み、WHERE句に設定するとWHERE句の二行下のMySqlDataReader reader = sqlCommand.ExecuteReader();というところでエラーがひっかかり、"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '[1].Value' at line 1"と出てしまいます。 dataGridView1.CurrentRow.Cells[1].ValueでSEQ_NOが取得できることは確認済なのですが、 WHERE SEQ_NO = dataGridView1.CurrentRow.Cells[1].Valueとして指定することは出来ないのでしょうか? 参考までに修正後ソースコードも追記させて頂きました。
YAmaGNZ

2019/09/15 05:00 編集

文字列と変数の違いを理解しましょう。 氏名での検索が出来ているのですから、分かるはずです。 また、こちら https://www.moonmile.net/blog/archives/1298 が参考になるかと思います。
ICCI

2019/09/16 11:46

ありがとうございます!参考にさせて頂き、無事に完成させることができました!
guest

0

ベストアンサー

UPDATE mst_address SET DEL_FLG = 1 WHERE SEQ_NO = dataGridView1.CurrentRow.Cells[1].Value

そのような UPDATE 文は文法的に間違っているのでダメです。クエリをパラメータ化してそれの Value に代入するようにしないと。

それより、WEHRE 句なして単純に UPDATE すればよさそうですけど。

まず、初期画面は以下の SELECT クエリで DataTabe に読み込んで、それを DataGridView にバインドして表示するのですよね?

SELECT SEQ_NO, NAME1,NAME2,ZIP1,ZIP2,ADDRESS1,ADDRESS2,ADDRESS3,TEL FROM mst_address WHERE DEL_FLG = 0

そして、ユーザーが DataGridView の画面を見て、削除したいレコードの DEL_FLG 列のチェックボックスにチェックマークを入れるのですよね?

そうであれば、ユーザーが編集完了後[削除]ボタンをクリックしたとき、そのイベントハンドラ DataGridView1_CellContentClick でユーザーが編集したすべての行を UPDATE すれば良いはずです。

そのような機能は DataSet/DataTable + DataAdapter に備わっているので、それを利用すれば容易にできると思います。

以下の記事の「非接続型のデータ更新」のセクションの図1と図2を見てください。見るのはとりあえず図だけでいいです。興味が湧いたら説明も読んでください。

DB 設計者のための明解 ADO.NET 第 1 回
https://docs.microsoft.com/ja-jp/previous-versions/cc482903(v=msdn.10)

そのような構造にすれば、ユーザーが DataGridView を操作・編集した結果は上の記事の図1にあるように DataSet / DataTable に反映されます。もちろん DEL_FLG にチェックを入れた結果もです。

編集作業終了後、ユーザーが[削除]ボタンをクリックすることにより DataAdapter に Update メソッドをかければ、上の記事の図2のように DataAdapter によって SQL が自動的に発行され、SQL Server のテーブルが更新されます。

DB が SQL Server の場合ですが(MySQL の場合も Visual Studio に同等な機能を追加できます)、以下のチュートリアル、

10 行でズバリ !! 非接続型のデータ アクセス (ADO.NET) (C#)
https://code.msdn.microsoft.com/windowsdesktop/10-ADONET-C-cbfe7688

のように Visual Studio のデータソース構成ウィザードを利用して型付 DataSet + TableAdapter を作って、それを利用してアプリを作ると、

DataGridview ⇔ BindingSource/BindingNavigator ⇔ DataSet/DataTable ⇔ DataAdapter ⇔ DB

と言う構造、すなわち以下のページの図のような構造のアプリが、ほとんど自分でコードを書くこと無しに作れます。

Windows フォーム アプリケーションでのデータへの接続
https://docs.microsoft.com/ja-jp/previous-versions/wxt2cwcc(v=vs.120)

上に紹介したチュートリアルは 2 つのテーブルを階層更新するために少々複雑になっていますが、単一テーブルですともっと簡単で、操作に慣れると以下のようなアプリが 5 分もかからず作れるはずです。

イメージ説明

今回のケースですと、削除は、DataGridView に DEL_FLG 列があるはずなのでそれにユーザーがチェックを入れると、内部の DataTable の当該 DEL_FLG 列が健康されその行には図1でいう Modified マークがつきます。その後、フロッピーディスクのアイコンをクリックすれば DB のテーブルに編集結果が反映されます。

自力で一からコードを書く場合のような種々の問題に悩むことはなくなり、開発工数は激減するはずです。保守工数も減るはずです。

お試しください。

【追伸】

MySQL で Visual Studio の TableAdapter 構成ウィザードを利用する場合、Visual Studio のウィザードが使う MySql.Data.dll のバージョン 6.9.8 と、GAC の MySql.Data.dll のバージョン 6.9.9 に不一致があって、それが原因でウィザードが期待通り動かないということがありましたので注意してください。

対処方法はバージョンを一致察せることです。詳しくは以下の記事を見てください。

MySQL での TableAdapter 構成ウィザード不具合
http://surferonwww.info/BlogEngine/post/2018/02/10/tableadapter-configuration-wizard-does-not-work-properly-for-mysql.aspx

上記は MySQL Installer 5.7.17 の話で、それ以外でどうなっているか(直ったのか、変わってないのか、さらに悪くなっているのか等)は不明です。

投稿2019/09/15 05:25

編集2019/09/15 05:52
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ICCI

2019/09/16 11:47

ご丁寧に教えてくださり、ありがとうございます!お陰様で無事に完成させることができました!
guest

0

テーブルにユーザーIDみたいなものはありますか?ないなら一意となるIDを追加した方がいいと思います?
ユーザーID列を一覧に追加して、表示したくないなら非表示にして、削除するときにその列を参照すればいいのではないのでしょうか

投稿2019/09/09 00:22

shirokuma4690

総合スコア154

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問