紧急:关于是否建临时表的问题(100分)

  • 主题发起人 主题发起人 windflower
  • 开始时间 开始时间
W

windflower

Unregistered / Unconfirmed
GUEST, unregistred user!
有一个listbox,它是用来显示“发票号”的(用户可以选择多个发票号);还有个
grid,是用来显示相应的发票号对应的商品信息。因为listbox中items的值不是来自
基本表的,请问我在写sql语句的时候该怎么写呢?是不是必须建一个临时表来存储
listbox的items,有没有别的办法(listbox中值比较多,要考虑速度和效率)?
谢谢!
 
用不着的,你只要使用Query查出要显示的记录让其显示出来就可,
这时它是在内存中的,同你用个临时表一样。
 
如果不建,那:
譬如“商品信息表”如下:
发票号 商品名称
fph1 aa
fph2 bb
fph3 cc
fph4 dd
fph10 ee
......
listbox中的值为: fph1,fph2,fph10
请问我的sql语句该怎样写呢?
 
如果需要创建一个临时表来保存listbox的值,请问该如何创建?谢谢!
 
你要选出这些东东终归有条件的吧。
select 发票号 from test where ......
 
条件就是:listbox.items.string(i=0 to listbox.items.count-1)
=“商品信息表”中的发票号即可。
 
procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;sqlstr: String;
begin
if listbox1.SelCount>0 then
for I:=0 to listbox1.items.count-1 do
begin
if listbox1.Selected then
begin
sqlstr:=sqlstr+' 发票号="'listbox1.items.strings+'"';
sqlstr:=sqlstr+' or ';
end;
end;
//去掉最后的一个‘or’
sqlstr:=copy(sqlstr,1,length(sqlstr)-2);
sqlstr:='select * from tablename where '+sqlstr;
query.close;
query.sql.text:=sqlstr;
query.open;
end;
//最后形成‘where 发票号=fph1 or 发票号=fph2 ...’的格式
 
这个办法可能会生成一个很长的sql语句,而query.sql.text的值好象不能超过255,我
想如果listbox中的值非常多的话,也许就不好了。请问还有别的办法吗?
 
query的sql是TStrings类,它的text属性并没有字数的限制。并且不论你最终使用什么
方法实现该功能,始终都要从listbox1中循环取出选中的值,如果你根据这些值生成临时
表或使用其它方法,还不如直接生成一个sql字符串来的快捷。
 
我上次是这样用的:
with adoquery1 do
begin
with sql do
begin
close;
clear;
text:=' '; //举个例子
end;
open;
end;
编译时系统提示text的长度不能超过255。
此外,如果我生成了临时表的话,我的sql语句可以这样写了:
select * from 商品信息表 a
where a.发票号 in (select 发票号 from 临时表)
临时表的结构是:ID 发票号 (发票号的值来自listbox.items)
这样可以吗?我想问有没有更好的办法?如果非要建临时表,该怎么建呢?
谢谢!
 
text的长度肯定可以超过255,如果不是你的程序那里有毛病,就是你的delphi还没
升级。delphi的补丁中对ado做了许多修正。
 
可能是delphi未升级的问题吧。因为我编了一个测试小程序,只有查询功能的。我想
在目前的环境下解决问题,譬如说就建一个临时表吧,请问该怎样建,我手里没什么资料,
谢谢!
 
哪位朋友举个例子,好吗?谢谢。
 
你用的是什么数据库,如果支持select...into可以先使用select...into建立临时表
query1.close;
qeury1.sql.text:='select 发票号 into #temp_tbl from 商品信息表 where 1=2 ';
query1.execsql;
//以上建立了一个包含一个字段的临时表,当用户断开连接后,数据库会自动删除该表
database1.StartTransaction;
try
for I:=0 to listbox1.items.count-1 do
begin
if listbox1.selected then
query1.sql.text:='insert into #tmep_tbl(发票号) values(''''
+listbox1.items.strings+''''+')';
query1.execsql;
end;
database1.commit;
except
database1.rollback;
end;
不过这样做实在太笨了,如果你只是提供查询,不允许用户修改。我建议你生成一个商品
信息表的临时表(只有结构)。然后用循环查找listbox中的值,构成sql语句(不超过
255即可),如要超过则执行该sql,把结果插入到临时表
使用insert into ... select语句
然后继续在listbox中查找选中的值,生成新的sql语句...
 
我用的是sql server
 
如果是sql server,设置数据库的属性,把options页中的select into/bulk copy
选中,就可以使用select into 创建临时表。
 
是啊,干吗要建立临时表呢?
listbox1.items.Clear;
with q1 do
begin
sql.clear;
sql.add('select ...');
open;
if recordcount > 0 then
while eofdo
begin
listbox1.items.add(fields[0].Asstring);
next;
end;
end;

至于右边信息的显示,可以用一个带参数的Query完成:
procedure TForm1.listbox1change...
begin
if listbox1.itemindex > 0 then
q2.params[0].AsString := listbox1.items[listbox1.itemindex];
q2.open;
//if not a dbgrid, then fill data yourself here
end;
 
text:=' ';

Delphi中String常量长度是不能超过255字节的。但你可以用

text:=' '+' '+' '啊
 
完全没有必要建立临时表
我做过类似的东西
sql.text的长度没有限制,随你怎么加好了,这个也不是常量啊
我看可以这么解决(我也是这么解决的):
在一个循环里把listbox中被选中的items都读到一个字符串里,逗号自己加:
strfph := 'fph1,fph2,...'
然后
select * from 商品信息表 a
where a.发票号 in (strfph)
完事大吉。
 
左轻侯的办法很好,bald_eagle也可以。
 
后退
顶部