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

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

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

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

SQL

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

Q&A

解決済

4回答

9302閲覧

C#でSQL文BETWEENの書き方

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

SQL

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

0グッド

0クリップ

投稿2017/06/27 05:58

編集2017/06/27 06:26

C#

1int id = 3; 2int minAge = 20; 3int maxAge = 50;

C#

1cmd.CommandText = "INSERT INTO [dbo].[Table2] ([ID], [年齢])" + 2"SELECT [ID], [年齢] FROM [dbo].[Table]" + 3"WHERE ID = N'" + id + "'"; 4if(minAge != null && maxAge != null) 5{ 6 cmd.CommandText += "AND 年齢 = N'BETWEEN" + minAge + "AND" + maxAge + "'"; 7}

上記のような条件でBETWEENの構文を適用したいのですがうまくいきません。
C#では文字列として読み込んでしまうため、エラーが出てくれたらいいのですが・・・
つまり構文が間違っているのかなと思い色々調べてみましたができませんでした。

C#

1cmd.CommandText = "INSERT INTO [dbo].[Table2] ([ID], [年齢])" + 2"SELECT [ID], [年齢] FROM [dbo].[Table]" + 3"WHERE ID = N'" + id + "'"; 4if(minAge != null && maxAge != null) 5{ 6 cmd.CommandText += "AND 年齢 = N'BETWEEN" + minAge + "'AND'" + maxAge + "'"; 7}

このように最後の列のANDの両端に'を追加するとエラーが出てしまい実行できません。
{"An expression of non-boolean type specified in a context where a condition is expected, near '50'."}
と出てきます。

どこが間違っているのか教えてください。
intには関係の無い文字化けを防ぐNを記載していますが、これはありでお願いいたします。
よろしくお願いいたします。

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

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

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

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

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

guest

回答4

0

直接の回答ではないです。

SQL インジェクション防止とパフォーマンス向上のためクエリは必ずパラメータ化しましょう。

すべての話はそれから(=パラメータ化してないクエリは議論するに値しない)と言っても過言ではないと個人的には思います。

パラメータ化クエリ
http://surferonwww.info/BlogEngine/post/2012/02/02/Parameterized-query.aspx

パラメータ化には SQL インジェクション防止とパフォーマンス向上以外にも副次的な効用があります。例えば下記:

パラメータ化の副次的な効用
http://surferonwww.info/BlogEngine/post/2016/06/04/use-parameterized-query-to-avoid-unexpected-character-corruption.aspx

今回の質問者さんの問題にも、パラメータ化クエリを使っていれば悩むことはなかったと思います。

投稿2017/06/27 06:52

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

まずは実行可能なSQLを書いて、

SQL

1INSERT INTO [dbo].[Table2] ([ID], [年齢]) SELECT [ID], [年齢] FROM [dbo].[Table] WHERE ID = 1 AND 年齢 BETWEEN 10 AND 20

C#の文字列にして、

C#

1"INSERT INTO [dbo].[Table2] ([ID], [年齢]) SELECT [ID], [年齢] FROM [dbo].[Table] WHERE ID = 1 AND 年齢 BETWEEN 10 AND 20"

パラメータクエリなり

C#

1"INSERT INTO [dbo].[Table2] ([ID], [年齢]) SELECT [ID], [年齢] FROM [dbo].[Table] WHERE ID = @ID AND 年齢 BETWEEN @MINAGE AND @MAXAGE"

べた書きパラメータに

C#

1"INSERT INTO [dbo].[Table2] ([ID], [年齢]) SELECT [ID], [年齢] FROM [dbo].[Table] WHERE ID = " + id + " AND 年齢 BETWEEN " + minAge + " AND " + maxAge

書き換えてみたらどこがおかしいか切り分けできるのではないでしょうか。
+演算子で改行したいのであればその後で。

投稿2017/06/27 06:25

workaholist

総合スコア559

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

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

0

まずSQLとしてBetween句の使い方おかしいですよね。

参考:SQL BETWEEN演算子

また、文字列連結をしてますが、行末および行頭に空白文字が入っていないため、連結結果がSQLとして文法エラーになる可能性が高いです。

"WHERE ID = N'" + id + "'";

ここの行末に「;」がついてるので、C#としてはここで文字列連結行は終了してますね。

投稿2017/06/27 06:07

tkturbo

総合スコア5572

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

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

退会済みユーザー

退会済みユーザー

2017/06/27 06:14

すみません。自分が書いていたコードを質問用に作り直しているのですが手違いがありました。 正しくは編集し直しましたのでもう一度見ていただければ幸いです。 お手数をおかけして申し訳ございません。
guest

0

ベストアンサー

; で文字列が閉じてしまっています。

csharp

1"INSERT INTO [dbo].[Table2] ([ID], [年齢])" + 2"SELECT [ID], [年齢] FROM [dbo].[Table]" + 3"WHERE ID = N'" + id + "'"; // ←これ 4"AND 年齢 = N'BETWEEN" + minAge + "'AND'" + maxAge + "'";

【追記】

余談ですが、この SQL を入れた変数を一度画面やログで出力してみると良いです。識別が繋がってしまっていてちゃんと動いていない、といった物が発見出来ます。あとこれは好き好きですが

csharp

1 var sql = @" 2 SELECT 3 * 4 FROM 5 TABLE1 6 ";

と書く方法もあります。(嫌いな人もいます)

【さらに追記】

BETWEEN は BETWEEN ここから AND ここまで という記述にならないといけません。ちなみに年齢(Age)ですので文字列ではないと思われます。なのでなぜ N を使っているか分かりません。

csharp

1 cmd.CommandText = "INSERT INTO [dbo].[Table2] ([ID], [年齢]) " + 2 "SELECT [ID], [年齢] FROM [dbo].[Table] " + 3 "WHERE ID = N'" + id + "'"; 4 if(minAge != null && maxAge != null) 5 { 6 cmd.CommandText += " AND 年齢 = BETWEEN " + minAge + " AND " + maxAge; 7 }

が正しいと思いますが、如何でしょうか。
P.S. コードブロックでは sql でなく csharp をお使い下さい。

投稿2017/06/27 06:03

編集2017/06/27 06:19
mattn

総合スコア5030

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

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

退会済みユーザー

退会済みユーザー

2017/06/27 06:14

すみません。自分が書いていたコードを質問用に作り直しているのですが手違いがありました。 正しくは編集し直しましたのでもう一度見ていただければ幸いです。 お手数をおかけして申し訳ございません。
退会済みユーザー

退会済みユーザー

2017/06/27 06:41

質問用に作り変えているので実際はint型ではなくstring型で行っているためNを付けています。 しかし、言われてみればstring型をint型にキャストしてしまえば同じことですね! なのでint型にキャストしてmattnさんのコードで試してみましたがやはりダメでした。 {"Invalid column name 'BETWEEN20AND50'."}と出てきました。 cmd.CommandText += " AND 年齢 = 'BETWEEN " + minAge + " AND " + maxAge + "'"; にするとエラーは出ませんが結果を得られませんでした。 何が原因なのかよくわかりません。。。
mattn

2017/06/27 06:42

シングルクォート消して下さい。
mattn

2017/06/27 06:43

あと = も要りません。 年齢 BETWEEN 15 AND 25 となる文字列を作って下さい。
退会済みユーザー

退会済みユーザー

2017/06/27 06:51 編集

cmd.CommandText += "AND 年齢 BETWEEN" + minAge + "AND" + maxAge; でやると下記のエラーが出てしましました。。 {"An expression of non-boolean type specified in a context where a condition is expected, near 'BETWEEN20AND50'."} 何度もすみません。
mattn

2017/06/27 06:54

えと、回答に書いた内容をちゃんとコピーして使って下さい。空白が消えてしまっていますよ。回答では BETWEEN の後や AND の前後に空白が入っています。落ち着いて、ゆっくり。
退会済みユーザー

退会済みユーザー

2017/06/27 06:58

原因は空白でした。。。。 本当に助かりました。 長々と私にお付き合いしていただきありがとうございました。
mattn

2017/06/27 07:01

ベストアンサーになってしまいましたが、SurferOnWww さんの回答があるべき姿ですのでご検討下さい。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問