如何在运行时根据用户选的不同的字段,用户定的不同的查询条件生成查询(200分)

  • 主题发起人 主题发起人 ayay99
  • 开始时间 开始时间
A

ayay99

Unregistered / Unconfirmed
GUEST, unregistred user!
我想在程序运行时给用户一个字段列表,用户根据该列表自己选择要查询的
字段,自己定义字段的查询条件,可这些我在编程时统统不知道,我该如何下
手?
我记得以前曾看到别人用tstringgrid做的,但现在找不到了
 
自己根据用户的选择拼SQL语句!
 
1、先通过BDEAPI将某TABLE的字段全部读到一StringGRID(或ComboBox中)。
2、建立用户界面
3、程序大体如下:
。。。
begin
Query1.Close;
Query1.SQL.Clear;
Query1.SQL.Add('select ') //记得空格
for i=0 to stringgrid.count-1 do
if 被选中 then
Query1.SQL.Add( stringgrid[2,i)
Query1.SQl.Add(' From '+tablename);
for i=0 to stringgrid2.count-1 /引号
Query1.Add(' where '+stringgrid2[1,i]+Combobox2+
+'='+char(34)+range+char(34)
大体这样。
 
根据用户选的字段拼很麻烦,
1、你不知道用户每回会选那种数据类型的字段,等用户选了字段后,在根据所选的
字段类型生成输入查询的窗口??
2、用户拼是不是不保险??
 
agree
我都是把所有字段都放在TCheckListBox,用户就可以选了.
然后为每一个可能查询条件放一个相应输入控件,如果用户有输入就作为查询条件
 
还是不明白,建立用户界面?怎么建立?可能的情况太多?
把可能的查询条件?不过这种可能太多如何处理?
从有40个字段的表中任取30个执行,用上述方法就烦琐的不行了。

 
checkbox--->列出字段名 或用listbox列出各表的字段
(注:应保持被查询表之间的联系)
checkbox--->列出每个字段的查询条件
初始用 字段<(>or=..):paramname
字段名被选择,语句中加字段名
查询条件被选择,parambyname(paramname):=条件
条件可用edit或combobox等提供
 
ayay99的意思是如果表有AA,BB两个字段,
那么可以给用户随便选择其中的一个或几个然后指定
aa>10 and bb<200这样一个条件
做综合查询,是吧?
我以前写过这样的例子,是先让用户挑一个字段,选择条件,
然后加入一个TListBox,再选一个,再加入……
最后把TListBox里的条件转换成SQL语句放在select * from table1 where ...
的后面就得了。在处理第一步的时候要先判断是什么类型的字段(可以读到的),
如果是字符就让他选“等于、包含”,如果是数字就“>、 =、 <”然后给个值,
每个判断一下,最后查询就可以了。
 
用DBGRID,字段下拉,运算符作成PICKLIST,拼成SQL语句就行了,我已做了一个。
 
我比较同意adminis的说法,但我想问一下adminis:
怎样字段类型?
 
adminis的说法正合我意但你能把你以前的例子给我吗?或给点代码。
阿朱的办法听着也可行,希望你能在详细的说明
 
以前的代码变量繁多,提炼一下:
先判断字段的类型,可以直接用Field.DataType属性得到。
有ftString, ftInteger, ftBoolean, ftFloat, ftDateTime...
得到以后:
if sFieldType='c' then // 字符型
begin
with cbMethod.Items do //cbMethod:TComboBox
begin
clear;
Add('等于');
Add('包含');
end;
end
else // 日期型、数字型和其它类型
with cbMethod.Items do
begin
clear;
Add('等于');
Add('大于');
Add('小于');
Add('不等于');
end;

当用户设好一个条件,按确定时,把该条件加入一个TStringList
var sFieldName, sFieldType, sMethod, sValue, sEnSql : string;
begin
if sFieldType='c' then // 字符运算
begin
if cbMethod.Text='等于' then
sEnSql := Format('(%s=''%s'')', [sFieldName, sValue])
else if cbMethod.Text='包含' then
sEnSql := '(' + sFieldName + ' like ''%' + sValue + '%'')';
if sValue = '' then sEnSql := Format('(%s or (%s is null))', [sEnSql, sFieldName]);
end
else if sFieldType='d' then // 日期运算
begin
if cbMethod.Text='等于' then sMethod := '='
else if cbMethod.Text='大于' then sMethod := '>='
else if cbMethod.Text='小于' then sMethod := '<='
else if cbMethod.Text='不等于' then sMethod := '<>';
if sValue = '' then
sEnSql := Format('((%s %s 0) or (%s is null))', [sFieldName, sMethod, sFieldName])
else
sEnSql := Format('(%s %s ''%s'')', [sFieldName, sMethod, sValue]);
end
else // 数字运算
begin
if cbMethod.Text='等于' then sMethod := '='
else if cbMethod.Text='大于' then sMethod := '>='
else if cbMethod.Text='小于' then sMethod := '<='
else if cbMethod.Text='不等于' then sMethod := '<>';
if sValue = '' then
sEnSql := Format('((%s %s 0) or (%s is null))', [sFieldName, sMethod, sFieldName])
else
sEnSql := Format('(%s %s %s)', [sFieldName, sMethod, sValue]);
end;
SqlLists.Add(sEnSql);

做完这些再把得到的多个条件做一个循环放到最后的SQL语句里面,

以上代码仅供参考,具体界面和功能的补充请根据需要进行扩充。
 
adminis言之有理,我按照你的方法编一下,如我功成名就你一定会财源滚滚。
 
adminis
您能告诉我如何取字段的数据类型吗?最好有代码!谢谢!
阿朱,你能说说您的办法吗?
 
adminis的方法好,有没有更好的呢?

 
等没有定义
case form1.Query1.Fields.Fields[num].datatype of
ftstring,ftword,ftwidestring:
sfieldtype:='s'; //string
ftfloat,ftcurrency.ftinteger,ftsmallint:
sfieldtype:='n'; //number
ftdate,fttime,ftdatetime:
sfieldtype:='d'; //date
end;
请大侠指教,这个问题解决后马上给分
 
刚才帖的有问题,我刚帖的代码在编译时不通,请指教!
 
你把DB单元加入到你的单元中没有。
因如:ftstring,ftinteger...等常量
是在DB单元中定义的。
 
多人接受答案了。
 
可是, 关于多表之间的联系呢? 比如: 在一个人事管理系统中, 专业是用代码表示的, 在查询时, 总不能给人家看代码吧? 得把代码对应的专业名称显示出来, 这就用到多表联接, 有什么好办法可以简单解决吗? 还有, 在选择字段时, 也得显示外部的中文字段名, 也需要一个对照表, 把表内的英文字段名翻译成中文, 有什么高招吗?
 
后退
顶部