各位朋友:下面的Delphi代码经测试已经可以正常运行,但查询速度太慢,希望有朋友可以耐心地看一看小弟的文档,能帮忙将小弟的代码改为存储过程,以提高效率,万分感谢!!!逻辑运算思路是这样的,有两个表,表1叫“zzbrkb_mx_phb(织机部牌号表)”,该表的字段有kwph(货物批号),wz(位置),ph(牌号) 
表2叫“zzbfkb(织机部收发表)”,该表的字段也有kwph(货物批号),wz(位置),ph(牌号),表3叫“zzbrkb_mx_phb_tmp(临时表,用来供用户查询用)”
另外,调用这个存储过程之后,马上使数据可以显示出来
程序规定了用户,如果输入多个牌号用“-”这个符号来隔开,例如,输入牌号1和2,就写“1-2”,输入牌号1和3,就写“1-3” 
程序最终的目的是想找出,表1里面有哪些牌号PH,还没有发货,也就是说,表1的哪些牌号(PH)没有出现在表2的牌号PH里面,但表2的牌号(PH)有以下四种情况
第一种:完全匹配型,即表1 有牌号(PH)为1,表2里发货就会输入牌号(PH) “1” 即 where 表1.kwph=表2.kwph and 表1.wz=表2.wz and 表1.ph=表2.ph
第二种:部分匹配型,即几个牌号同时发货,而且该牌号写在最前面,即表1 有牌号(PH)为1,表2里发货时同时发1的牌号和2的牌号,就会写成 “1-2”
即 where 表1.kwph=表2.kwph and 表1.wz=表2.wz and 表1.ph like('1-%')
第三种:部分匹配型,即几个牌号同时发货,而且该牌号写在中间位置,即表1 有牌号(PH)为1,表2里发货时同时发1、2、3的牌号,有可能会写成 “2-1-3”
即 where 表1.kwph=表2.kwph and 表1.wz=表2.wz and 表1.ph like('%-1-%')
第四种:部分匹配型,即几个牌号同时发货,而且该牌号写在最后位置,即表1 有牌号(PH)为1,表2里发货时同时发1、2、3的牌号,有可能会写成 “3-2-1”
即 where 表1.kwph=表2.kwph and 表1.wz=表2.wz and 表1.ph like('%-1')Delphi里面的逻辑运算的思路是这样的,用户首先输入要查询的货物批号kwph和位置wz,然后查询该货物批号的该位置下有没哪牌号没有发货1、首先将临时表里面的内容全部清空,即delete from zzbrkb_mx_phb_tmp2、然后根据用户输入的kwph+wz来作一个Select,即select * from zzbrkb_mx_phb where kwph=用户输入的kwph and wz=用户输入的wz3、做完这一个动作后,会先定位到第一条记录,然后从第一条记录开始,获取第一条记录的kwph、wz、ph,然后在zzbfkb里面进行第一次select(假设发货的时候
,该牌号PH是完全匹配型)即select kwph from zzbfkb where kwph= + QuotedStr(kwph_tmp) + ' and wz=' + QuotedStr(wz_tmp) + ' and ph =' + QuotedStr(ph_tmp)),如果这时查到记录的话,就证明该牌号已经发货,那么就可以移动到下一条记录继续进行判断了4、但如果找不到该记录,那么就假设该牌号是部分匹配型,而且牌号PH写在最前面,那么就按下面的运作进行selectselect kwph from zzbfkb where kwph=' + QuotedStr(kwph_tmp) + ' and wz=' + QuotedStr(wz_tmp) + ' and ph like' + QuotedStr(ph_tmp + '-' + '%')
如果这时查到记录的话,就证明该牌号已经发货,那么就可以移动到下一条记录继续进行判断了5、但如果找不到该记录,那么就假设该牌号PH写在中间的位置,那么就按下面的运作进行selectselect kwph from zzbfkb where kwph=' + QuotedStr(kwph_tmp) + ' and wz=' + QuotedStr(wz_tmp) + ' and ph like' + QuotedStr('%' + '-' + ph_tmp + '-' + '%')如果这时查到记录的话,就证明该牌号已经发货,那么就可以移动到下一条记录继续进行判断了5、但如果找不到该记录,那么就假设该牌号PH写在最后的位置,那么就按下面的运作进行selectselect kwph from zzbfkb where kwph=' + QuotedStr(kwph_tmp) + ' and wz=' + QuotedStr(wz_tmp) + ' and ph like' + QuotedStr('%' + '-' + ph_tmp)6、如果这时查到记录的话,就证明该牌号已经发货,那么就可以移动到下一条记录继续进行判断了,但假如进行了上面的4种SELECT之后,还是找不到该牌号PH的话,那么就说明该牌号PH还没有发货,即该牌号在表1(zzbrkb_mx_phb)里面存在,但在表2(zzbfkb)里面不存在,这时就要将该牌号记录出来,我在Delphi里面是将该牌号的记录,插入到临时表里面去的(zzbrkb_mx_phb_tmp),做完这个动作之后,将记录定位到下一条记录,然后重复步聚3-6,直到定位到最后一条记录7、做完以上所有的动作之后,就查询临时表(zzbrkb_mx_phb_tmp),因为这个时候,该表保存了用户想查询的数据
以下是Delphi里面的代码procedure Tfrm_zzbphb_cx.Button1Click(Sender: TObject);
var
kwph, wz, ph: string;
kwph_tmp, wz_tmp, ph_tmp: string;
find_ok: Integer;
begin
find_ok := 0;
if (DBEditEh1.Text = '') or (ComboBox1.Text = '') then
begin
ShowMessage('货物批号和位置不能为空!');
exit;
end;
kwph := trim(DBEditEh1.Text);
wz := trim(ComboBox1.Text);
ShowMessage('该操作需要花费一定的时间,请耐心稍侯!');
Screen.Cursor := crHourGlass;
try
with ado_phb do
begin
DisableControls;
begin //先将这个表原来查询的结果清空,开始
Close;
sql.Clear;
sql.Text := 'delete from zzbrkb_mx_phb_tmp where kwph=' + QuotedStr(kwph) + ' and wz=' + QuotedStr(wz);
ExecSQL;
end; //先将这个表原来查询的结果清空,结束
begin //将原来的结果清空后,首先从原来的牌号表选择对应的牌号和位置,然后从上到下,一条一条进行判断,开始
Close;
sql.Clear;
sql.Text := 'select * from zzbrkb_mx_phb where kwph=' + QuotedStr(kwph) + ' and wz=' + QuotedStr(wz);
Open;
First;
while not Eof do //准备一条一条记录地进行循环判断
begin
kwph_tmp := fieldbyname('kwph').AsString; //先获取原来牌号表对应的货物批号
wz_tmp := fieldbyname('wz').AsString; //先获取原来牌号表对应的位置
ph_tmp := fieldbyname('ph').AsString; //先获取原来牌号表对应的牌号
if DM.get_BySql('select kwph from zzbfkb where kwph=' + QuotedStr(kwph_tmp) + ' and wz=' + QuotedStr(wz_tmp) + ' and ph =' + QuotedStr(ph_tmp)) <> '' then //对牌号进行匹配式查找
find_ok := 1; //返回的值不为空,即表示在发货表里面已经有了这个牌号,所以将find_ok这个变量赋值为1,表示该牌号已经有发货记录了
if find_ok = 0 then //这个变量为0,表示未没有找到该牌号,假设这个牌号是在第一个位置,即用10-%这种方式来进行查找
begin
if DM.get_BySql('select kwph from zzbfkb where kwph=' + QuotedStr(kwph_tmp) + ' and wz=' + QuotedStr(wz_tmp) + ' and ph like' + QuotedStr(ph_tmp + '-' + '%')) <> '' then
find_ok := 1;
end;
if find_ok = 0 then //这个变量为0,表示用了第一种查找还没有找到该牌号,假设这个牌号是在中间位置,即用%-10-%这种方式来进行查找
begin
if DM.get_BySql('select kwph from zzbfkb where kwph=' + QuotedStr(kwph_tmp) + ' and wz=' + QuotedStr(wz_tmp) + ' and ph like' + QuotedStr('%' + '-' + ph_tmp + '-' + '%')) <> '' then
find_ok := 1;
end;
if find_ok = 0 then //这个变量还是为0,表示用了中间的这一种查找还没有找到该牌号,假设这个牌号是在最后位置,即用%-10这种方式来进行查找
begin
if DM.get_BySql('select * from zzbfkb where kwph=' + QuotedStr(kwph_tmp) + ' and wz=' + QuotedStr(wz_tmp) + ' and ph like' + QuotedStr('%' + '-' + ph_tmp)) <> '' then
find_ok := 1;
end;
if find_ok = 0 then //用了上面的四种查找方式,这个变量还是0的话,就说明该牌号根本没有发过货,所以要开始进行插入记录操作
begin
with dm.Qry_select do //开始将没有找到的牌号进行插入操作
begin
Close;
sql.Clear;
sql.Text := 'insert into zzbrkb_mx_phb_tmp values(:kwph, :wz, Ph)';
Parameters.ParamByName('kwph').Value := kwph_tmp;
Parameters.ParamByName('wz').Value := wz_tmp;
Parameters.ParamByName('ph').Value := ph_tmp;
ExecSQL;
end;
end
else
find_ok := 0; //赋一个初值给这个变量,以实现下一个牌号的查找
ado_phb.Next;
end;
end; //将原来的结果清空后,首先从原来的牌号表选择对应的牌号和位置,然后从上到下,一条一条进行判断,结束
//进行完上面的所有操作之后,对zzbrkb_mx_phb_tmp这个表进行SELECT操作,看看有没有记录,如果有的话,就证明该记录没有发货,如果没有,就证明该批该位置已经发货完毕
Close;
sql.Clear;
sql.Text := 'select * from zzbrkb_mx_phb_tmp where kwph=' + QuotedStr(trim(DBEditEh1.Text)) + ' and wz=' + QuotedStr(trim(ComboBox1.Text));
Open;
if Recordset.RecordCount >= 0 then
statusbar1.Panels[1].Text := inttostr(recordset.RecordCount);
EnableControls;
if IsEmpty then
ShowMessage('批号为' + DBEditEh1.Text + ',位置为' + ComboBox1.Text + '已经全部发货完毕!')
else
ShowMessage('请注意,还有未发货的牌号!');
end;
except
ShowMessage('操作过程遇到窗误,请关闭本窗体,然后重新进入,进行查询操作!');
end;
Screen.Cursor := crDefault;
end;