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

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

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

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Access

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

SQL

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

Q&A

解決済

2回答

13069閲覧

【VS C#】Textboxから取得したstringで検索クエリ

kamiokabegami

総合スコア13

C#

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Access

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

SQL

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

0グッド

0クリップ

投稿2018/11/12 11:27

編集2018/11/16 03:50

前提・実現したいこと

VSのWindowsフォーム、C#にて簡単なデータベースシステムを作っています。
tblTank(Name, Nationality, Status....)というテーブルから、Nameで検索して該当するものだけ表示するクエリをTextboxを使って実装しようとしています。
クエリ自体は動いているようなのですが、結果がどんな値を入れてもNULLで返ってきてしまいます。
C言語のみ経験があり、学校の課題ということでC#でやっています。SQLやVSもあまり慣れておらず、どうすればいいのか全く見当がつきません。

該当のソースコード

SQL

1//Nameは文字列で、txtNameはTextboxに当たります。 2SELECT * 3FROM Tank 4WHERE Name LIKE "txtName.Text"

ただし、以下のように具体的な文字や数字を指定するとしっかりと結果を返してくれます。

SQL

1SELECT * 2FROM Tank 3WHERE Name LIKE "T34"

試したこと

txtName.Textの前後にワイルドカードを挿入したり、一度string型に格納してから同様の処理を行うなどはしてみましたが、結果は変わらずです。

補足情報(FW/ツールのバージョンなど)

VS 2017
DBはAccessで、VS内のデータソースから読み込んでいます。

検索をするフォーム部分のコードです

C#

1 2using System; 3using System.Collections.Generic; 4using System.ComponentModel; 5using System.Data; 6using System.Drawing; 7using System.Linq; 8using System.Text; 9using System.Threading.Tasks; 10using System.Windows.Forms; 11 12namespace PanzerEliteDB 13{ 14 public partial class frmNameSearch : Form 15 { 16 public frmNameSearch() 17 { 18 InitializeComponent(); 19 } 20 21 private void tankBindingNavigatorSaveItem_Click(object sender, EventArgs e) 22 { 23 this.Validate(); 24 this.tankBindingSource.EndEdit(); 25 this.tableAdapterManager.UpdateAll(this.woTDBDataSet); 26 27 } 28 29 private void frmNameSearch_Load(object sender, EventArgs e) 30 { 31 // TODO: This line of code loads data into the 'woTDBDataSet.Tank' table. You can move, or remove it, as needed. 32 this.tankTableAdapter.Fill(this.woTDBDataSet.Tank); 33 34 } 35 36 private void button1_Click(object sender, EventArgs e) 37 { 38 39 this.tankTableAdapter.FillBy3(this.woTDBDataSet.Tank); 40 } 41 42 private void nameToolStripButton_Click(object sender, EventArgs e) 43 { 44 try 45 { 46 this.tankTableAdapter.FillBy3(this.woTDBDataSet.Tank); 47 } 48 catch (System.Exception ex) 49 { 50 System.Windows.Forms.MessageBox.Show(ex.Message); 51 } 52 53 } 54 55 private void nameToolStrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e) 56 { 57 58 } 59 60 private void tankBindingNavigator_RefreshItems(object sender, EventArgs e) 61 { 62 63 } 64 } 65}
お二方ご回答ありがとうございました。 YAmaGNZさんに教えていただいた方法で何とかクエリを完成させることができました。 パラメータ化クエリは少し勉強が必要だと今回は判断し、今後自分用のDBに勉強しながら取り組んでみます。

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

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

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

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

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

YAmaGNZ

2018/11/12 12:11

そのSQLを構築する部分のC#のソースを提示してください。
退会済みユーザー

退会済みユーザー

2018/11/13 01:50

補足情報を見て私の回答欄に追記しました。そちらを見てください。DB が何かの情報もよろしく。スルーは NG。フィードバックは必ず返してください。
guest

回答2

0

ベストアンサー

SQLにC#側の変数を書いても、それが変数として扱われることはありません。

ソースから察するに、VisualStudioのデータソース デザイナを使用してFillBy3を作成されたのだと思います。
そのデザイナのSQLを入力するところで@Nameというような感じで@をつけるとパラメータとして扱われるようになります。
パラメータはプログラム側で変更しようとする変数のようなものだと考えてください。

SQL

1SELECT * 2FROM Tank 3WHERE Name LIKE @Name

とすれば
例
このように@Nameと引数が表示されるはずです。
そうすれば、コードのほうで

C#

1this.tankTableAdapter.FillBy(this.woTDBDataSet.Tank,TextBox1.Text);

といった感じで引数に追加できるようになるはずです。

追記
タグを見ていませんでした。
Accessであれば、?ですね
こちらが参考になるかと思います。
また、Likeの使い方はこちらを参照してください。

投稿2018/11/13 00:57

編集2018/11/13 22:42
YAmaGNZ

総合スコア10242

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

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

退会済みユーザー

退会済みユーザー

2018/11/13 01:06

DB が何かを聞いてから回答した方がよさそうです。タグを見ると Access ではないかと想像してますが・・・
kamiokabegami

2018/11/13 07:55

DBはAccessです。 ご紹介いただいた方法で試してみます。
kamiokabegami

2018/11/13 08:20 編集

C#の方での、パラメータへの値の受け渡しはどうすればできるのでしょうか…? 他のサイトも参考にしてみましたが、よくわかりませんでした。 ちなみにSQLに@Nameを追加したときに ```エラー The wizard detected following problems when configuring TableAdapter query "ByName": Details: Generated SELECT statement. Error in WHERE clause near '@'. Unable to parse query text. ``` これはDBがAccessであることに起因する問題なのでしょうか?
YAmaGNZ

2018/11/13 08:22

DBがAccessの場合は、追記で紹介したページにあるとおり、?を使います。 Name Like ? といったように書いてください。
kamiokabegami

2018/11/13 22:27

ああ、Accessの場合は不明なのかと受け取っていました。 トライしてみます
kamiokabegami

2018/11/14 06:46

教えていただいた方法でできました。 ちなみにint型を同じ方法で引き渡すことはできないのでしょうか? 二つのint型を引き渡して、数値の範囲を指定したいのですがうまくいきません。 下のようにしたいと考えています。 WHERE Tier = [? - ?]
YAmaGNZ

2018/11/14 07:11

範囲指定は Tier >= ? AND Tire <= ? もしくは Tier BETWEEN ? AND ? になるかと思います。 ここらへんは、SQLの文法になります。 実行できるSQLを構築し、変数として代入したい部分を?とすると考えると分かりやすいかと思います。
kamiokabegami

2018/11/14 23:08

この際の引数の引き渡しは単純に this.TableAdapter.Query(this.DataSet.Table, int1, int2) という風にすればよいのでしょうか? このようにやってみたのですがうまくいきませんでした…
YAmaGNZ

2018/11/15 00:38

うまくいかないとはどういう状況でしょうか? コンパイルエラーとなるのでしょうか? 実行したらエラーとなるのでしょうか? 実行した結果、期待している結果にならないのでしょうか? 「うまくいかない」は便利な言葉ですが、何をやってどうなったか説明がないと回答したくても出来ません。
kamiokabegami

2018/11/15 04:42

申し訳ありません、引数の引き渡しの時に?の型と引数の型があっていなかっただけのようです。
guest

0

C# ということですから、ADO.NET を使うのですよね? であれば、クエリをパラメータ化して、TextBox.Text の値をパラメータに代入するようにしてください。

やり方は「パラメータ化クエリ」をキーワードにググればわかると思いますが、不明な点があれば聞いてください。その際は、DB が何か(SQL Server? Access? MySQL? その他?)を書いてください。

【追記】

補足情報を見ると、Visual Studio のデーターソース構成ウィザードを使って型付 DataSet / DataTable + TableAdapter を生成して使っていて、すでに DataGridView に全レコードの一覧を表示し、それを編集して結果を DB に反映するところまではできているようですね。

さらに、それに TextBox と Button を追加して検索機能を持たせようとしているのですか?

であれば、DB に検索用のクエリを投げるのではなくて、全レコードはすでに DataSet / DataTable に取得済みなので、それをフィルタリングして DataGridView に表示した方がよさそうです。

詳しい方法が不明でしたら聞いてください。DB が何かの情報もよろしく。

【追記2】

上の追記で、

DB に検索用のクエリを投げるのではなくて、全レコードはすでに DataSet / DataTable に取得済みなので、それをフィルタリングして DataGridView に表示した方がよさそうです。

と書きましたが、そのコード例を書いておきます。

使った DB は SQL Server の Northwind サンプルデータベースの Products テーブルです。button1_Click メソッドで DataTable.DefaultView.RowFilter を使ってフィルタリングしているところに注目してください。

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form3 : Form { public Form3() { InitializeComponent(); } private void productsBindingNavigatorSaveItem_Click(object sender, EventArgs e) { this.Validate(); this.productsBindingSource.EndEdit(); this.tableAdapterManager.UpdateAll(this.northwindDataSet); } private void Form3_Load(object sender, EventArgs e) { this.productsTableAdapter.Fill(this.northwindDataSet.Products); } private void button1_Click(object sender, EventArgs e) { if (!String.IsNullOrEmpty(this.textBox1.Text)) { NorthwindDataSet.ProductsDataTable table = this.northwindDataSet.Products; table.DefaultView.RowFilter = "ProductName LIKE '%" + this.textBox1.Text + "%'"; this.productsBindingSource.DataSource = this.northwindDataSet.Products; } else { NorthwindDataSet.ProductsDataTable table = this.northwindDataSet.Products; table.DefaultView.RowFilter = ""; } } } }

TextBox に "cha" と入力して Search ボタンをクリックし、ProductName LIKE '%cha%' で検索した結果が下の画像です。

イメージ説明

投稿2018/11/12 21:01

編集2018/11/13 05:33
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

kamiokabegami

2018/11/13 07:54

反応が遅くなり申し訳ありません パラメータ化クエリなるものを自分でも調べてみたのですが、よくわからず、少し立ち戻ったところから見直し始めたところです。 のちに補足にも追記しますが、DBはAccessです。 どの方法で自分が理解できるか少し試してみます…
kamiokabegami

2018/11/13 08:13

少し話がずれますが、このelse分岐では、TextBoxがNullであった場合、"(空白)"に合致する部分、すなわちテーブル全体を表示するという解釈であっていますか?
退会済みユーザー

退会済みユーザー

2018/11/13 08:56

合ってます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問