• 締切済み

SQL文がうまく通らないのですが

プログラミング初心者です。ご指導お願いします。 以下のセレクト文を作ったのですが、SQL文がうまくできません。 select ~~~~(省略) AND DELIVERY_DATE between " + fromYear + fromMonth + " and " + toYear + toMonth; 表示はこうなります AND DELIVERY_DATE between 20084 and 20086; 年と月が区別されないみたいなのですが、 どう直せばよろしいですか? 一人で勉強していて、詰まってしまい質問させていただきました。 助けていただけるとありがたいです。

みんなの回答

  • public_sa
  • ベストアンサー率52% (13/25)
回答No.7

文字列を数値としてって所も躓いているようなので ちょっと変更・補足で fromYearが2008 fromMonthが12 だった場合 "DELIVERY_DATE between " + (( Integer.parseInt(fromYear) * 10000) + ( Integer.parseInt(fromMonth) * 100)) + " and " "DELIVERY_DATE between " + ((20080000) + (1200)) + " and " は "DELIVERY_DATE between " + ((20081200)) + " and " は "DELIVERY_DATE between 20081200 and " となります。 ちなみにfromYearもfromMonthもどっかから渡ってくるパラメータで あるなら入力チェックをしないとNumberFormatExceptionなり例外が発生 する状況になる場合が考えられますので パラメータチェックをすることをお勧めしますし、 もし本当にどっかから渡ってくるパラメータなら fromYear に 「1 and 2 or true or 」と文字列入力されたら 全てのデータが出てきてしまいますのでパラメータチェックなり PreparedStatementを使うのを考えた方がよさそうですね。

somehow123
質問者

お礼

回答ありがとうございました。 非常にわかりやすい説明で感謝してます。 解決できました。

  • public_sa
  • ベストアンサー率52% (13/25)
回答No.6

autyさんの通りだとは思いますが、 文字列と数値の「+」演算結果について基本的な所を1つ 文字列と数値の演算は左から順に評価され 文字列+数値1+数値2+数値3の演算結果は文字列として扱われます。 先に数値として足し算したい部分は下記の様に()で囲う必要があります。 文字列+数値1+(数値2+数値3) は 文字列+数値1+数値2&3の演算結果 となり これが文字列として連結され結果となります。 fromYearが2008 fromMonthが12 だった場合 somehow123さんのSQLの例だと "DELIVERY_DATE between " + ( fromYear * 10000) + ( fromMonth * 100) + " and " は "DELIVERY_DATE between " + (20080000) + (1200) + " and " は "DELIVERY_DATE between 20080000" + (1200) + " and " は "DELIVERY_DATE between 200800001200 " + " and " は "DELIVERY_DATE between 200800001200 and "となります。 だから結果が思わしくなかったということでしょうか。 8桁の数値でDELIVERY_DATEをBETWEENで評価したければ "DELIVERY_DATE between " + (( fromYear * 10000) + ( fromMonth * 100)) + " and " とするべきだったのではないでしょうか? somehow123さんのSQLとは()の数が違いますね。 "DELIVERY_DATE between " + (( fromYear * 10000) + ( fromMonth * 100)) + " and " は "DELIVERY_DATE between " + ((20080000) + (1200)) + " and " は "DELIVERY_DATE between " + ((20081200)) + " and " は "DELIVERY_DATE between 20081200 and " となります。 あまりこういった風に日付を扱ったことないので質問を見たときにピンと来なかった です。 というよりも大きな御世話も知れませんが、8桁の数値で日付を管理するなら DELIVERY_DATEの型をDATE型で持ったほうが扱いやすいのではないかと思います。 datediff()とかで日数も求められますし、その他いろいろな関数が用意されていますしね。 日付が要らないのであれば常に01日で評価するとか。 余談ですがテーブルの型の変更もデータを削除せず ALTER TABLE 文で変更できます。 勉強になるかも知れませんよ。 一人で勉強してて大変かもしれないですが、頑張ってください。

somehow123
質問者

お礼

回答ありがとうございました。 非常にわかりやすい説明で感謝してます。 解決できました 最後の一言で救われました。ありがとうございます。

  • auty
  • ベストアンサー率58% (284/486)
回答No.5

DELIVERY_DATE between " + ( fromYear * 10000) + ( fromMonth * 100) + " and " + toYear + toMonth のところは、 DELIVERY_DATE between " + ( fromYear * 100 + fromMonth ) + " and " + ( toYear*100 + toMonth ) でしょうか。

  • auty
  • ベストアンサー率58% (284/486)
回答No.4

・ まだ、DELIVERY_DATEのデータ型が出てきていないようですが、   テーブルのカラムDELIVERY_DATEのデータ型とその実際のデータのサンプルを示していただけますか。 ・ それから念のために、select文のwhere句全体もお知らせください。

somehow123
質問者

お礼

すいません、たてこんでて書き込みが遅れました。 DELIVERY_DATEのデータ型はINTです。 セレクト文は以下です select dlv.supplier_id, sup.sort_order, dlv.order_no, dlv.delivery_date, sup.supplier_name , dlv.parts_name, dlv.amount, dlv.unit_price, dlv.sum_money from trn_delivery dlv left join mst_supplier sup on dlv.supplier_id = sup.supplier_id where ORDER_NO like '%" + searchId + "%'  AND DELIVERY_DATE between " + ( fromYear * 10000) + ( fromMonth * 100) + " and " + toYear + toMonth where ORDER_NO like '%" + searchId + "%'までのSQL文は間違いなく通っています。 よろしくおねがいします。

somehow123
質問者

補足

すいません、たてこんでて書き込みが遅れました。 DELIVERY_DATEのデータ型はINTです。 セレクト文は以下です select dlv.supplier_id, sup.sort_order, dlv.order_no, dlv.delivery_date, sup.supplier_name , dlv.parts_name, dlv.amount, dlv.unit_price, dlv.sum_money from trn_delivery dlv left join mst_supplier sup on dlv.supplier_id = sup.supplier_id where ORDER_NO like '%" + searchId + "%'  AND DELIVERY_DATE between " + ( fromYear * 10000) + ( fromMonth * 100) + " and " + toYear + toMonth 5行目までのSQL文は間違いなく通っています。 よろしくおねがいします。

  • public_sa
  • ベストアンサー率52% (13/25)
回答No.3

問題点は幾つか考えられるのですが、 情報が少なすぎて分かりませんが まずはきっちり通るSQLを作成し後から変数化すると 良いと思いますし。。。。 1. 前の方の通り DELIVERY_DATE between 20084 and 20086;でなく DELIVERY_DATE between 200804 and 200806; というか DELIVERY_DATE between "200804" and "200806";かな 2. DELIVERY_DATEの型次第でDATE型っだったりした場合は (MySQL) DELIVERY_DATE between DATE("20080401") and DATE("20080601"); (ORACLE) DELIVERY_DATE between TO_DATE('20080401') and TO_DATE('20080601'); 3. DELIVERY_DATE がNumber型やInteger型などだった場合 AND DELIVERY_DATE between 20084 and 20086; でSQL分自体は正しいですが DELIVERY_DATEの値が200805となっていた場合 between 20084 and 20086; では条件外となってしまいます。 他にもいろいろ考えられますのでご参考までに。。。

somehow123
質問者

お礼

回答ありがとうございます。 FromYear,FromMonth,Toyear,ToMonth はすべてString型なので、 Yearには10000を、Monthには100をかける必要があるようなんですが、それがよくわからないんです。 日付はテキストエリアで入力するようになっています。

  • auty
  • ベストアンサー率58% (284/486)
回答No.2

・ 勘違いしたようです。   2桁の月と比べるには、 01,02,03,... とする必要があるかも知れません。

  • auty
  • ベストアンサー率58% (284/486)
回答No.1

・ そもそも DELIVERY_DATE between '20084' and '20086' となるように、SQL分を作成すべきではないでしょうか。 まず、 DELIVERY_DATE between '" + fromYear + fromMonth + "' and '" + toYear + toMonth + "'" の様にしてみてください。

somehow123
質問者

お礼

回答ありがとうございます。 FromYear,FromMonth,Toyear,ToMonth はすべてString型なので、 Yearには10000を、Monthには100をかける必要があるようなんですが、それがよくわからないんです。