SQL文をやってます。
Edit1に入力された値を”年”として、さらに”月”を指定し、”入力された年 AND 月”をLIKEを使って表示させようとしてます。
Query1.SQL.Add('Select フィールド名 From テーブル名 Where Hyou1.日付 Like ('+Sonotosi+'/01) ');
Hyou1・・・テーブル名
日付・・・ フィールド名(日付型)
Sonotosi・・・Edit1に入力された値(文字列型)
これだと、エラー”式中の型が一致しません”とでます。
フィールド(日付)の型とEdit1の型が違うからですか?としたら、入力された値を日付型にすれば・・・という問題ではないみたいなので、どのようにすればよいか助言をいただきたいと思ってます。
最初はLIKEではなく、ワイルドカードというのを使ってました。が、ヘルプに書かれてあったのは・・・'2007/01/..'とあったのですが、
Query1.SQL.Add('Select フィールド名 From テーブル名 Where Hyou1.日付 ('+Sonotosi+'/01/..) ');
SonoTosiに2007と入力された場合・・・
エラー
キーワードの使用が無効です
キーワード:(2007/01/..)
行番号:1.
とでます。これも型が関係しているのでしょうか?
>フィールド(日付)の型とEdit1の型が違うからですか?
SQL文の中で、Edit1の型まで見てはいません。
SQL文は、単に文字列でSQL文を渡しているだけです。
書かれているものは、SQL文の中に文字列値の記述をする部分で
間違っている様な?
この辺は、ここの過去の書き込みからでも探してみてください。
LIKE演算子は、文字列マッチングですので 日付型へは無理です。
・お使いのデータベースのSQL文で使用可能な文字型変換関数があれば、日付型を文字列に変換した値と LIKE演算子は使えます。
・年・月が解るのであれば、その値から月初めと月末日付を求めて
Between演算子を使えば 範囲抽出が可能です。
・お使いのデータベースで、日付型から、年 及び月を取り出す関数があるのでしたら、年・月それぞれを=で条件付けできます。
日付の範囲であれば、Betweenが無難だとは思います。
LIKE演算子は文字列パターンの比較なので使用するのであれば、
CAST関数を用いてHyou1.日付の型を文字列型に変換する必要があります。
もう一点は検索値も当然文字列となるので
Sonotosi + '/01) '
の部分を引用符で括る必要があります。
該当年月を絞り込むのなら期間指定で指定したほうがいいような気がしますが(;^ ^)
Betweenを使ってみました。
Query1.SQL.Add('SELECT Hyou.日付,Simei.氏名,Kubun.区分,Hyou.開始時刻 Hyou.終了時刻,Hyou.普通勤務時間・・・
FROM Hyou,Simei,Kubun
WHERE (Simei.CodeKubun=Kubun.Code)AND(Hyou.日付 BETWEEN ('+MTosi+'/01/01)AND('+MTosi+'/01/31))');
※
Hyouテーブル
日付
開始時刻
終了時刻
普通勤務時間
・
・
Simeiテーブル
Code
氏名
CodeKubun
Kubunテーブル
Code
区分
MTosi・・・Edit1に入力された”年”
これだと
エラー
キーワードの使用が無効です。
キーワード: =Kubun.Code)AND(Hyou.日付
ためしにBetween部だけにすると
・・・
WHERE Hyou.日付 BETWEEN ('+MTosi+'/01/01)AND('+MTosi+'/01/31)');
エラー
キーワードの使用が無効です。
キーワード: BETWEEN
・・・どう修正すればよいのか分かりません。助言ください。
ANDの前後には、半角空白がありますか?
あと、Basser さんも書かれてますが、
日付は引用符で括るほうがよいかもしれません。
半角スペースは、入っていませんでした・・・なので入れました。
”引用符”・・・とは?
過去の書き込みから調べたら、AnsiQuotedStr関数というのがあったので、そのまま入れました。ヘルプで調べてはみましたが、理解できずに。
WHERE Hyou.日付 BETWEEN ('+AnsiQuotedStr(MTosi,'''')+'/01/01) AND ('+AnsiQuotedStr(MTosi,'''')+'/01/31)');
これで実行!・・・
エラー
キーワードの使用が無効です
キーワード: Kubun.Code)
なぜ?
またもやBETWEEN部だけで実験
WHERE Hyou.日付 BETWEEN ('+AnsiQuotedStr(MTosi,'''')+'/01/31)');
エラー
キーワードの使用が無効です
キーワード: BETWEEN
なぜ?
,'''')←これは何のためにあるのでしょうか。パラメータでしょうか?だとしたら何の?
=の前後には、半角空白がありますか?
あと、/01/01 や /01/31 も、AnsiQuotedStrの引数のほうに
入れたほうがよいかもしれません。
半角スペースはありませんでした。が、
WHERE (Simei.CodeKubun = Kubun.Code)AND(Hyou.日付 BETWEEN ('+MTosi+'/01/01)AND('+MTosi+'/01/31))');
とすると、
エラー
キーワードの使用が無効です。
キーワード: =
とでます。
それと、
”/01/01 や /01/31 も、AnsiQuotedStrの引数のほうに
入れたほうがよいかもしれません。”
これはAnsiQuotedStr(MTosi/01/01,'''')ということでしょうか?
私は、湘南乃海さんのお使いのDBをわかっていません。
先の質問から・・結局paradoxにされたのでしょうか?
であればと言うことで、PARADOXで書いてみました。
(Paradoxの日付書式のHELPを見てください。)
以下は、ダミーで私のPCにDiaryというテーブルを作成し
hiduke(日付型)でデータ抽出をしてみた例です
(Database DeskTopで確認済)
select * from diary where (hiduke Between "12/1/2000" and "12/31/2000")
正しく動作しています。
日付の書式が 月/日/年の形式の必要がります
このあたりは、DBを開発した国により違ったりします。
Queryをお使いなので、パラメータを使用される場合は
この限りではありません。
そうそう、最初に書いた方法の3番目ですがPARADOXであれば
select * from diary where EXTRACT(YEAR FROM hiduke) = 2000 and EXTRACT(MONTH FROM hiduke) = 12
hidukeから、年・月を取り出せるので 2000年12月として抽出もできます。
でも、BETWEENの方がよいとは思います。
余談ですが
画面から指定した年月から月末日付を算出する場合には
翌月の1日から1日マイナスした日付を求めると 確実です。
すいません。最初に書いておくべきでした。Paradoxです。
Paradoxのヘルプの日付書式を見てみると、月/年/年 で書かれてあったので、
WHERE (Simei.区分 = Kubun.Code) and (Hyou.日付 BETWEEN "01/01/'+AnsiQuotedStr(MTosi,'''')+'") AND ("01/31/'+AnsiQuotedStr(MTosi,'''')+'"))');
としてみます。といってもこの記述の仕方であっているのでしょうか。
あと、先ほどから実行しようとしてもエラーが出ます。
エラー
レコードは他のユーザーによってロックされています
テーブル:
ユーザー:
年月を指定ではなかったのでしょうか?
そのまま書き直すとしたら
WHERE (Simei.区分 = Kubun.Code) and (Hyou.日付 BETWEEN "01/01/'+ MTosi + '" AND "01/31/' + MTosi + '")'
でしょうか(Mtosiは文字列として)
ParadoxはD5のころ以降触っていないので うろ覚えですが
>レコードは他のユーザーによってロックされています
は、排他制御しているファイルを削除し他方が良いかも
なにも指定してないのであれば、c:\に PDOXUSRS.NET があれば
削除してください。(記憶あいまいなので、ちょっと自信なし)
日付を表す文字列は、データーベースによってまちまちです。
ParadoxのSQL文の場合は、"月/日/年"ですから、1月を表すのは、
Between "1/1/2007" and "1/31/2007"になります。
また、DelphiのTQueryでパラメターを使うと、
Query1(TQuery)のSQL文に
Select *
From テーブル名
where 日付 BETWEEN (:初日 AND :終日)
をセットして、
Query1.ParamByName('初日').AsDateTime := StrToDateTime('2007/1/1');
Query1.ParamByName('終日').AsDateTime := StrToDateTime('2007/1/31');
Query1.Open;
で選択できます。
>レコードは他のユーザーによってロックされています
は、IDEの開発中のDataBaseのプロパティでConected=Trueになっていませんか?AYさんのおっしゃる様に、制御ファイルを削除すれば直ります。
いろいろアドバイスをいただいた結果、これでOKのようです。
Query1.SQL.Add('SELECT Hyou.日付,Simei.氏名,Kubun.区分,Hyou.開始時刻,Hyou.終了時刻,Hyou.普通勤務時間,Hyou.普通残業時間,Hyou.割増残業時間
FROM Hyou,Simei,Kubun
WHERE Simei.区分 = Kubun.Code and
(Hyou.日付 BETWEEN "01/01/'+MTosi+'" AND "01/31/'+MTosi+'")');
レコードのロックの問題もAYさんのアドバイスで解決できました。
あと、AYさんの
”画面から指定した年月から月末日付を算出する場合には
翌月の1日から1日マイナスした日付を求めると 確実です。”
これはどう書けばよいのでしょうか。というのも、2月の部分で躓いてしまって。
"02/01/'+MTosi+'" and "03/01-1/'+MTosi+'"
でOKですか?
すいません、気になったことがもう一つ。
Paradoxの日付書式には”02/021/2007”
のような書き方になっていたのですが、データベースのテーブルに直接日付を入れてみたところ、”2007/02/21”とでます。
”02/021/2007”といれてみたところ、”月指定が不正です”とでます。
なので実験として2月のみコードを変更して
Query1.SQL.Add(・・・Hyou.日付 BETWEEN "'+MTosi+'02/01/" AND "'+MTosi+'02/28/")');
として実行し、2月を選ぶと
エラー
式中の型が一致しません
となります。これは・・・コードがおかしいのでしょうか。それとも何かの設定がおかしいのでしょうか。
つまり、”エラーは全て消えたけど考えどおりに表示されていない”ということですね。
なんか、試されているSQL分 めちゃくちゃになってますよ。
デバッガでとめて内容を確認するようにしないと、コードの問題か
コードの入力ミスの問題か識別できていないのではないでしょうか?
フォームにEdit1,2 ボタンをクリック時
Edit1の年とEdit2の月を使って開始・終了日付を求めています。
(Editの入力内容は未チェックですよ)
procedure TForm1.Button1Click(Sender: TObject);
Var
From_ymd : TDate; // 開始日付
To_ymd : TDate; // 終了日付
begin
// Edit1には、指定年 Edit2には指定月を入力している
// 月初め
From_ymd := StrToDate(Edit1.Text + '/' + Edit2.Text + '/01');
// 月末=月初めに1月足して-1日する
To_ymd := IncDay(IncMonth(From_ymd,1),-1) ;
MessageDlg('開始日付:'+FormatDatetime('yyyy/mm/dd',From_ymd) + #13 +
'終了日付:'+FormatDatetime('yyyy/mm/dd',To_ymd), mtInformation, [mbOK], 0);
MessageDlg('SQL開始日付:'+FormatDatetime('mm/dd/yyyy',From_ymd) + #13 +
'SQL終了日付:'+FormatDatetime('mm/dd/yyyy',To_ymd), mtInformation, [mbOK], 0);
end;
SQL分に埋め込む場合は、FormatDatetime('mm/dd/yyyy',To_ymd)を
お使いになるといいです。
SQL文は、ParadoxのLocalSQLの規約で書きます。
プログラムは、Delphiの言語で書きます。
この2つをごっちゃにしていませんか?
エラーを起こしているのが、プログラムなのかSQL文が間違っているのか
判らなくなります。
なんか自分でも混乱してきた気が・・・
SQL文を打っている最中に(・・・あれ?これってSQL文じゃねぇし! とかいう状態が何度も)
とにかくですね、これで(一部を除いて)大丈夫みたいです。
Query1.SQL.Add('SELECT Hyou.日付,Simei.氏名,Kubun.区分,Hyou.開始時刻,Hyou.終了時刻,Hyou.普通勤務時間,Hyou.普通残業時間,Hyou.割増残業時間
FROM Hyou,Simei,Kubun
WHERE Simei.区分 = Kubun.Code
and (Hyou.日付 BETWEEN "01/01/'+MTosi+'" AND "01/31/'+MTosi+'")');
DBGridにもちゃんと表示されてます。でも日付の表記は"2007/02/22"となっています。まぁいいんですけど。それと、一部に問題が。このSQL文のとおりに2月の文を書いてまして、
(Hyou.日付 BETWEEN "02/01/'+MTosi+'" AND "02/28/'+MTosi+'")');
としたところ(最初は02/29とやってみたのですが、エラーが出ました)、2月のDBGridだけ文字化けしてます。なのでAYさんの方法で月末を計算しようとしたのですが、
From_ymd := StrToDate(TTosi+ '/02/01');
To_ymd := IncDay(IncMonth(From_ymd,1),-1) ;
IncDayのところでエラーが出ます。
エラー
未宣言の識別子 IncDay
IncMonthは問題ありませんでした。
Uses節に DateUtils ユニットを追加しましょう。
IncDay関数をヘルプで見てください。どのユニットを使用しているか分かります。
>DBGridにもちゃんと表示されてます。でも日付の表記は"2007/02/22"となっています。まぁいいんですけど。
もしかして、02/01/2007でSQLで取ってきてるのに、2007/02/01に表示がなることを気にされてます?
02/01/2007と書くのは、そう書くのがParadoxの仕様だからです。
そうしないと、取ってこないのです。
それと日付表示の形式とは意味が違います。
表示は、PCで設定している表示形式です。
DateUtilsユニット追加しました。・・・今後気をつけます。
"02/01/2007でSQLで取ってきてるのに、2007/02/01に表示がなることを気にされてます?"
気になってました。でも問題ないみたいですね。
var
YMD1,YMD2:TDate;
y,m,d:word;
mm,dd:string;
・・・
YMD1:=strtodate(MTosi+'/02/01');
YMD2:=IncDay(IncMonth(YMD1,1),-1);
DecodeDate(YMD2,y,m,d);
mm:=inttostr(m);
dd:=inttostr(d);
Query1.SQL.Add(・・・ BETWEEN "02/01/'+MTosi+'" AND "'+mm+'/'+dd+'/'+MTosi+'")');
これでどうでしょう。実行してもエラーは出ません。が、相変わらず2月のみ文字化けしてます。(数字、記号()は正常) なぜなのかわかりません。
2月だけ、文字化けと言うのが どこがどう文字化けなのか
文面では?です。
最初は、年・月を入力するという意味じゃなかったのですか?
2月を固定で良いのでしょうか?
YMD1:=strtodate(MTosi+'/02/01');
YMD2:=IncDay(IncMonth(YMD1,1),-1);
ここまでされているのであれば
Query1.SQL.ADD(・・・・BetWeen "' + FormatDatetime('mm/dd/yyyy',YMD1) + '" and "' + FormatDatetime('mm/dd/yyyy',YMD2) + '"');
値を入力できるのは”年”のみです。月はこんな感じで(YMD1:=strtodate(MTosi+'/02/01');)あらかじめ指定しておきます。
文字化けしているのは文字列型のフィールド全てです。ほか(整数型、時間型、など)は無事です。
日付 氏名(文字列型) 区分(文字列型) 開始時間(時間型) ・・・
2007/02/22 (文字化け) (文字化け) 08:30 ・・・
2007/02/22 (文字化け) (文字化け) 09:00 ・・・
という感じです。AYさんの
Query1.SQL.ADD(・・・・BetWeen "' + FormatDatetime('mm/dd/yyyy',YMD1) + '" and "' + FormatDatetime('mm/dd/yyyy',YMD2) + '"');
をやってみたのですが、文字化け状態は変わりませんでした。
あと、前にレコードがロックされてる状態を"PDOXUSRS.NET を削除"で回避できたのですが、実行するたびにロックされて毎回削除しなければならない状態に陥ってます。(削除さえすれば実行はできます)
"IDEの開発中のDataBaseのプロパティでConected=Trueになっていませんか?"
とありましたが、DatabaseコンポーネントのConectedプロパティのことですよね?私Databaseコンポーネント置いてないんで、ほかに原因があるということでしょうか?
Database Desktopでテーブルを開いても、同様に2月だけが文字化けするのでしょうか?それとも往路グラムだけで文字化けするのでしょうか?
SQL文の月の記述で、文字型の項目があるときだけ化けるとかということは
通常考えられません。
事象を、SQLの書き方の不具合として捉えない方がいいと思います。
HOtaさんが書かれているように、別な形で確認して情報を。
あと、抽象的な書き方ですが、Paradoxはきれいに使っている限り
そうそうおかしくなりません。(そんな事ないと言う方もいらっしゃるでしょうが)
プログラムの全容が見えてないのですが、テストの途中で異常終了等させているとロックが掛ることはありました。
毎回なると言うのが解せませんが、正常にテーブルを閉じて問題なく終了させて見てください。同じことになりますか?
(先の質問でTurboと書かれていたので、Delphiでの扱いとは違うのかもしれませんが)
文字化け なおりました。
なんかごちゃごちゃしてたんで、テーブルごと作り直したり、SQL文も書きなおしたりしてたら、いつの間にかなおってました。やっぱりどこかぬけてたのか、間違えて書いてたりしてたのかもしれません。でも最初に作ったのは1月の分で、2月とか3月とかはコピーしたものだったんですけど・・・書き直すところが足りなかったりしたのかなぁ。
で、作り直している最中に新たな問題が・・・って、気付いたらタイトルとぜんぜんそれた場所にいましたね。SQL文にエラーはないみたいなので、解決にします。
ツイート | ![]() |