组合查询的问题(急!!!)帮帮我吧。(300分)

  • 主题发起人 liuzongyi
  • 开始时间
L

liuzongyi

Unregistered / Unconfirmed
GUEST, unregistred user!
小弟毕业设计做一个路侧紧急电话管理软件,要实现如下条件查询:范围、分机号、事件属性、起止日期
范围:range 可选项:全部呼叫 单机呼叫 全部检测 单机检测
分机号:phonenum 可选项:如01A之类的号码
事件属性:accident 可选项:全部事件 车辆求助 交通事故 匪警 火警 电话检测
起止日期:startdate,enddate
要求:范围选择全部呼叫或全部检测的时候,分机号选项输入无效(不列入查询)。
单机XX是有效,但分机号选择结果可有可无,有则列入查询条件。
事件属性选择全部事件的时候包含了车辆求助……电话检测所有事件。但是,车辆检测……火警
只能在范围选择XX呼叫时才有效,在选择XX检测时,时间属性只默认为电话检测。

我的数据库里面的相应字段:数据表Name:DataTable,数据库用的是SQL Server2000
序号:integer 分机号:char 事件属性:vchar 时间:char 格式:yyyy-mm-dd

我程序里的一部分:
RangeBox: TRadioGroup;
PhoneNumList: TComboBox;
AccidentInfoList: TListBox;
SpinEdit1: TSpinEdit;
SpinEdit4: TSpinEdit;
SpinEdit2: TSpinEdit;
SpinEdit5: TSpinEdit;
SpinEdit3: TSpinEdit;
SpinEdit6: TSpinEdit;
DataInfoQuery: TQuery;
procedure TDataCtrolCenter.QueryButtonClick(Sender: TObject);
var
range,phonenum,accident:string;
startdate,enddate:string;
year1,year2,month1,month2,day1,day2:word;
firstdate,seconddate:TdateTime;
sqlstr:string;
i,j:integer;
begin
range:=RangeBox.Items[RangeBox.ItemIndex];
phonenum:=PhoneNumList.Text;
accident:=AccidentInfoList.Items[AccidentInfoList.ItemIndex];
year1:=spinedit1.value;
year2:=spinedit4.value;
month1:=spinedit2.value;
month2:=spinedit5.value;
day1:=spinedit3.value;
day2:=spinedit6.value;
firstdate:=encodedate(year1,month1,day1);
seconddate:=encodedate(year2,month2,day2);
startdate:=formatdatetime('yyyy-mm-dd',firstdate);
enddate:=formatdatetime('yyyy-mm-dd',seconddate);
sqlstr:='Select * From DataTable Where';
:(其余的不会写了
帮帮我吧,我刚学Delphi,不会写这样的查询语句了。给我点源代码吧。

 
H

htw

Unregistered / Unconfirmed
GUEST, unregistred user!
写SQL语句或filter, 如果写SQL语句的话, 你还是找一本delphi入门书或者SQL相关的书籍
来看, 用filter可以看一下/dephi5/demos/db/Filter中的例子。
 
N

NetBird

Unregistered / Unconfirmed
GUEST, unregistred user!
我刚编了一个40个选项的组合查询,在某一选项中可以输入参数也可以不输,
只要有一个参数就可以了
具体实现是这样的:
var
a:string;
b:boolean;
begin
if edit1.text<>'' then
begin
a:='field1='+' '+edit1.text;
b:=true;
end
if edit2.text<>'' then
begin
if b=true then
begin
a:=a+' '+'and'+' '+'field2='+' '+edit2.text;
b:=true;
end;
end
else
begin
a:='field2='+' '+edit2.text;
b:=false
end;

if ...........

.
.
sql.add(select * from query where a)
 
L

liuzongyi

Unregistered / Unconfirmed
GUEST, unregistred user!
我的还有一些比较麻烦的逻辑呢,弄得我头都晕了,看看我写的说明
 
C

chenlh

Unregistered / Unconfirmed
GUEST, unregistred user!
一个一个用字符串穿起来就行了

 
L

liuzongyi

Unregistered / Unconfirmed
GUEST, unregistred user!
我写了这样的代码,编译通过,但我点击查询的时候说第一行附近有语法错误,大家给我查一查吧。 sqlstr:='Select * From DataTable Where';
if (Pos('单机',range)=1) and (Trim(phonenum)<>'') then
sqlstr:=sqlstr+'分机号='''+phonenum+''' AND ';
if accident='全部事件' then
begin
if Pos('呼叫',range)>0 then
sqlstr:=sqlstr+'事件属性<>''电话检测'' AND '
else
sqlstr:=sqlstr+'事件属性=''电话检测'' AND ';
end
else
sqlstr:=sqlstr+'事件属性='''+accident+''' AND ';
sqlstr:=sqlstr+'年月日>=''+startdate+''+ AND 年月日<=''+enddate''';
with DataInfoQuery do
begin
close;
SQL.Clear;
SQL.Add(sqlstr);
Prepare;
Open;
end;
最后那行sqlstr我在startdate和enddate前面用'''的时候编译通不过,说是有漏掉的符号。
给我查一查吧。

 
T

TomZhao

Unregistered / Unconfirmed
GUEST, unregistred user!
用SQL要简单点。用一个可变数组存放条件这样就可以实现组合查询
 
L

liuzongyi

Unregistered / Unconfirmed
GUEST, unregistred user!
with dataInfoquery do
begin
close;
Sql.clear;
Sql.add('Select * From DataTable where');
if Pos('单机',range)=1 then
begin
if phonenum<>'' then
Sql.add('分机号='''+phonenum+''');
if Pos('检测',range)>0 then
Sql.add(' and 事件属性=''电话检测''')
else
Sql.add(' and 事件属性='''+accident+''')
end
else
Sql.add('事件属性='''+accident+''');
Sql.add(' and 年月日>='+startdate+' and 年月日<='+enddate);
Sql.add(' Group by 年月日,序号,分机号,桩号');
prepare;
open;
end;
大家帮我检查以下错误,看是不是这样写的。我不会SQL的写法。
 
L

liuzongyi

Unregistered / Unconfirmed
GUEST, unregistred user!
好啦,我终于自己倒腾出来了,只不过比较罗嗦而已。我把它贴出来吧。
板主请给我自己加分哦:)下次再给大家分配分数。procedure TDataCtrolCenter.QueryButtonClick(Sender: TObject);
var
range,phonenum,accident:string;
startdatetmp,enddatetmp:string;
year1,year2,month1,month2,day1,day2:word;
firstdate,seconddate,startdate,enddate:TdateTime;
// sqlstr:string;
// i:integer;
begin
range:=RangeBox.Items[RangeBox.ItemIndex];
phonenum:=PhoneNumList.Text;
if AccidentInfoList.ItemIndex=(-1) then
AccidentInfoList.ItemIndex:=0;
accident:=AccidentInfoList.Items[AccidentInfoList.ItemIndex];
year1:=spinedit1.value;
year2:=spinedit4.value;
month1:=spinedit2.value;
month2:=spinedit5.value;
day1:=spinedit3.value;
day2:=spinedit6.value;
firstdate:=encodedate(year1,month1,day1);
seconddate:=encodedate(year2,month2,day2);
startdatetmp:=formatdatetime('yyyy-mm-dd',firstdate);
enddatetmp:=formatdatetime('yyyy-mm-dd',seconddate);
startdate:=StrToDate(startdatetmp);
enddate:=StrToDate(enddatetmp);
with dataInfoquery do
begin
close;
Sql.clear;
sql.Add('Select * From DataTable where'+#13#10);
if phonenum<>'' then
begin
Sql.Add('分机号='''+phonenum+'''');
if range='全部检测' then
begin
Sql.Add(' And 事件属性=''电话检测''');
Sql.add(' And (DataTable.年月日>=:starts');
Sql.add('And DataTable.年月日<=:ends'+')');
Sql.add(#13#10+'Group by 年月日,时间,分机号,主副机,序号,桩号,事件属性,备注');
Params[0].AsDatetime:=startdate;
Params[1].AsDatetime:=enddate;
end;
if range='单机检测' then
begin
Sql.Add(' And 事件属性=''电话检测''');
Sql.add(' And (DataTable.年月日>=:starts');
Sql.add(' And DataTable.年月日<=:ends'+')');
Sql.add(#13#10+'Group by 年月日,时间,分机号,主副机,序号,桩号,事件属性,备注');
Params[0].AsDatetime:=startdate;
Params[1].AsDatetime:=enddate;
end;
if range='全部呼叫' then
begin
if accident='全部事件' then
begin
Sql.add(' And (DataTable.年月日>=:starts');
Sql.add(' And DataTable.年月日<=:ends'+')');
Sql.add(#13#10+'Group by 年月日,时间,分机号,主副机,序号,桩号,事件属性,备注');
Params[0].AsDatetime:=startdate;
Params[1].AsDatetime:=enddate;
end
else
begin
if accident<>'' then
begin
Sql.Add(' And 事件属性='''+accident+'''');
Sql.add(' And (DataTable.年月日>=:starts');
Sql.add(' And DataTable.年月日<=:ends'+')');
Sql.add(#13#10+'Group by 年月日,时间,分机号,主副机,序号,桩号,事件属性,备注');
Params[0].AsDatetime:=startdate;
Params[1].AsDatetime:=enddate;
end
else
begin
Sql.add(' And (DataTable.年月日>=:starts');
Sql.add(' And DataTable.年月日<=:ends'+')');
Sql.add(#13#10+'Group by 年月日,时间,分机号,主副机,序号,桩号,事件属性,备注');
Params[0].AsDatetime:=startdate;
Params[1].AsDatetime:=enddate;
end;
end;
end;
if range='单机呼叫' then
begin
if accident='全部事件' then
begin
Sql.add(' And (DataTable.年月日>=:starts');
Sql.add('And DataTable.年月日<=:ends'+')');
Sql.add(#13#10+'Group by 年月日,时间,分机号,主副机,序号,桩号,事件属性,备注');
Params[0].AsDatetime:=startdate;
Params[1].AsDatetime:=enddate;
end
else
begin
if accident<>'' then
begin
Sql.Add(' And 事件属性='''+accident+'''');
Sql.add(' And (DataTable.年月日>=:starts');
Sql.add('And DataTable.年月日<=:ends'+')');
Sql.add(#13#10+'Group by 年月日,时间,分机号,主副机,序号,桩号,事件属性,备注');
Params[0].AsDatetime:=startdate;
Params[1].AsDatetime:=enddate;
end
else
begin
Sql.add(' And (DataTable.年月日>=:starts');
Sql.add(' And DataTable.年月日<=:ends'+')');
Sql.add(#13#10+'Group by 年月日,时间,分机号,主副机,序号,桩号,事件属性,备注');
Params[0].AsDatetime:=startdate;
Params[1].AsDatetime:=enddate;
end;
end;
end;
end
else
begin
if range='全部检测' then
begin
Sql.Add('事件属性=''电话检测''');
Sql.add(' And (DataTable.年月日>=:starts');
Sql.add(' And DataTable.年月日<=:ends'+')');
Sql.add(#13#10+'Group by 年月日,时间,分机号,主副机,序号,桩号,事件属性,备注');
Params[0].AsDatetime:=startdate;
Params[1].AsDatetime:=enddate;
end;
if range='单机检测' then
begin
Application.MessageBox('请选择分机号!','没有输入分机号',
MB_OK+MB_Defbutton1+MB_IconInformation+MB_SystemModal);
Sql.Clear;
Sql.add('Select * From DataTable');
end;
if range='全部呼叫' then
begin
if accident='全部事件' then
begin
Sql.add('(DataTable.年月日>=:starts');
Sql.add(' And DataTable.年月日<=:ends'+')');
Sql.add(#13#10+'Group by 年月日,时间,分机号,主副机,序号,桩号,事件属性,备注');
Params[0].AsDatetime:=startdate;
Params[1].AsDatetime:=enddate;
end
else
begin
if accident<>'' then
begin
Sql.Add('事件属性='''+accident+'''');
Sql.add(' And (DataTable.年月日>=:starts');
Sql.add(' And DataTable.年月日<=:ends'+')');
Sql.add(#13#10+'Group by 年月日,时间,分机号,主副机,序号,桩号,事件属性,备注');
Params[0].AsDatetime:=startdate;
Params[1].AsDatetime:=enddate;
end
else
begin
Sql.add('(DataTable.年月日>=:starts');
Sql.add(' And DataTable.年月日<=:ends'+')');
Sql.add(#13#10+'Group by 年月日,时间,分机号,主副机,序号,桩号,事件属性,备注');
Params[0].AsDatetime:=startdate;
Params[1].AsDatetime:=enddate;
end;
end;
end;
if range='单机呼叫' then
begin
Application.MessageBox('请选择分机号!','没有输入分机号',
MB_OK+MB_Defbutton1+MB_IconInformation+MB_SystemModal);
Sql.Clear;
Sql.add('Select * From DataTable');
end;
end;
prepare;
open;
end;
end;
 
Z

zhangkan

Unregistered / Unconfirmed
GUEST, unregistred user!
有时在写动态SQL时能用循环写的就最好用循环写,又快又不易出错.我发觉我现在越来越喜欢
写SQL了。
 
L

liuzongyi

Unregistered / Unconfirmed
GUEST, unregistred user!
板主,麻烦您结束此贴,给chenlh,htw,NetBird,TomZhao,zhangkan各加20分,
其余的留给我自己:)
 
P

pingbaoshi

Unregistered / Unconfirmed
GUEST, unregistred user!
来自:fstao, 时间:2000-6-27 8:54:00, ID:272424
其实很简单,假如任意组合查询三个字段:

var
sqlstring:string;
begin
if edit1.text<>'' then
begin
sqlstring:=' field1='''+edit1.text+'''';
end;
if edit2.text<>'' then
begin
if sqlstring<>'' then
begin
sqlstring:=sqlstring+' and field2='''+edit2.text+'''';
end
else
begin
sqlstring:=' field2='''+edit2.text+'''';
end;
end;
if edit3.text<>'' then
begin
if sqlstring<>'' then
begin
sqlstring:=sqlstring+' and field3='''+edit3.text+'''';
end
else
begin
sqlstring:=' field3='''+edit3.text+'''';
end;
end;

with query1 do
begin
close;
sql.clear;
sql.add('select field1,field2,field3 from dbo.table1 where ');
sql.add(sqlstring);
open;
end;
end;

 
Z

zs

Unregistered / Unconfirmed
GUEST, unregistred user!
关于怎么写前面都写了,我想说的是,在动态生成sql时,我一般用:
“ select * from table1 where 1=1 ”
后面的条件就可以是," and a=b "," and c=d"...
这样应该会好一点,
另外,你有40个选项的模糊查询,你当然要写40个条件了![:D]
 

荷塘新月

Unregistered / Unconfirmed
GUEST, unregistred user!
多动动脑筋吧,不劳是难以收获的,即使收获了也不会是硕果!
 

千中元

Unregistered / Unconfirmed
GUEST, unregistred user!
接受答案了.
 
A

andyyejiang

Unregistered / Unconfirmed
GUEST, unregistred user!

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
598
import
I
S
回复
0
查看
814
SUNSTONE的Delphi笔记
S
I
回复
0
查看
559
import
I
顶部