我创建了一个返回整数值的主查询,有2个次要条件来限制在侧面组合框中选择。
一切都适用于设定的参数。我希望我能用侧面组合框关闭或打开这些条件,我该怎么办?
我的代码在Delphi中:
procedure TForm1.Button3Click(Sender: TObject);
begin
FDQuery3.Close;
FDquery3.Params[0].Value := Datetimepicker1.Date;
FDquery3.Params[1].Value := Datetimepicker2.Date;
FDQuery3.Params[2].Value := Combobox3.Items [Combobox3.Itemindex];
FDQuery3.Params[3].Value := Combobox5.Items [Combobox5.Itemindex];
FDQuery3.Open;
end;
SQL文本是:
select
G.NUM_PROG,T.DATA,T.ORA,C.DESCRIZIONE,
(select DESKEY from ANAFORN where CODKEY=T.CODICE ) as Cliente,
O.NOMINATIVO, T.TERMINALE,T.INCASSO
from LG_RIGHE G
inner join LG_TESTA T on G.NUM_PROG =T.NUM_PROG
inner join OPERATORI O on T.OPERATORE = O.CODICE
inner join LG_CAUSA C on T.CAUSALE = C.CODICE
where T.DATA >= :data1
and T.DATA <= :data2
and T.INCASSO = :pagamento
and T.TERMINALE = :terminale
order by G.NUM_PROG
我只想打开/关闭Params [2] [和Params [3](名称:pagamento,terminale)
答案 0 :(得分:1)
1)可选地忽略条件的典型方法是再添加一个&#34;切换&#34;参数。考虑一下这个Delphi代码
Result := True; // or False. Actually - some previous part of formula
If Need_Check_Option_A then
Result := Result and ( Option_A > 20 );
If Need_Check_Option_B then
Result := Result and ( Option_B < 10 );
知道了吗? 但很长一段时间,是否有更简洁的方式来编写它?
Result := .....some other parts....
and (Ignore_Option_A or (Option_A > 20 ))
and (Ignore_Option_B or (Option_A < 10 ))
and ....
现在让我们将它从Delphi重新表达为SQL WHERE子句
WHERE (.......) and (......)
AND ( ( :Use_pagamento = 0 ) or ( T.INCASSO = :pagamento ) )
AND ( ( :Use_terminale = 0 ) or ( T.TERMINALE = :terminale ) )
是否将USE_xxxx参数设置为零(类似于false),则第二次检查将是快捷方式,忽略。
调用代码就像
FDquery3.ParamByName('data1').AsDate := Datetimepicker1.Date;
FDquery3.ParamByName('data2').AsDate := Datetimepicker2.Date;
FDQuery3.ParamByName('pagamento').AsString := Combobox3.Items [Combobox3.Itemindex];
FDQuery3.ParamByName('terminale').AsString := Combobox5.Items [Combobox5.Itemindex];
FDQuery3.ParamByName('Use_pagamento').AsSmallInt := Ord( CheckBox3.Checked );
FDQuery3.ParamByName('Use_terminale').AsSmallInt := Ord( CheckBox5.Checked );
更多建议如下:
2)使用像ComboBox3
这样的名字是不好的。你不明白他们的意思,他们打算做什么。看看你的SQL - 你在那里给出了名字!你没有像
SELECT FIELD1, FIELD2 FROM TABLE1 WHERE FIELD3 < :PARAM1
你必须给你的Delphi对象提供合理的名字!
那个FDQuery3
,Checkbox3
Combobox5
- 将它们全部重命名,给了他们一些有意义的名字!{/ p>
3)你有一个嵌套选择作为Cliente
列。除非特殊情况缓慢且效率低下 - 将其更改为JOIN
(可能更改为LEFT JOIN
,如果有时没有匹配值)
select
G.NUM_PROG,T.DATA,T.ORA,C.DESCRIZIONE,
-- (select DESKEY from ANAFORN where CODKEY=T.CODICE ) as Cliente,
A.DESKEY as Cliente,
O.NOMINATIVO, T.TERMINALE,T.INCASSO
from LG_RIGHE G
inner join LG_TESTA T on G.NUM_PROG =T.NUM_PROG
inner join OPERATORI O on T.OPERATORE = O.CODICE
inner join LG_CAUSA C on T.CAUSALE = C.CODICE
/* left */ join ANAFORN A on A.CODKEY=T.CODICE
where T.DATA >= :data1
and T.DATA <= :data2
AND ( ( :Use_pagamento = 0 ) or ( T.INCASSO = :pagamento ) )
AND ( ( :Use_terminale = 0 ) or ( T.TERMINALE = :terminale ) )
order by G.NUM_PROG
4)根据具体情况,您可能只想更改SQL文本。 如果参数将被忽略 - 那么只需删除它!
这个选项不是普遍的,但它有好的和坏的方面。 但是在你的情况下,它宁愿做好事也不做任何事 - 因为你有人重新打开查询,而人类不能每秒做一次而不是每秒一次。
好:然后服务器获取您准备QUERY PLAN的SQL文本。如何获取数据的内部程序。并且它还不知道您的参数是什么,因此它准备PLAN以始终检查这些参数。即使你以后会忽略它们。有时它可能会使服务器选择缓慢的PLAN,如果它知道参数不会被使用,它可以选择更快的。有时它没有任何区别。运气的游戏。
错误:如果您保持SQL文本相同,那么您可以PREPARE
一次查询,当您使用不同参数重新打开查询时,服务器不会构建不同的PLAN
。但是,如果您确实更改了SQL文本,那么服务器必须解析该新查询并在它为您提供数据之前再次准备PLAN。有时,当您打开关闭查询(例如每秒1000次)时需要相当长的时间。当然,当你使用人工设置那些复选框,组合框然后按下按钮时,他不会经常这样做,所以在这种情况下风险是没有实际意义的。
所以在你的情况下你可能会做这样的事情,而不是引入那些toggle参数:
var qt: TStrings; // SQL query text
.....
qt := FDQuery3.SQL;
qt.Clear; // changing SQL Text would auto-close the query
qt.Add('select G.NUM_PROG,T.DATA,T.ORA,C.DESCRIZIONE, ');
qt.Add(' A.DESKEY as Cliente, O.NOMINATIVO, T.TERMINALE,T.INCASSO ');
qt.Add('from LG_RIGHE G ');
qt.Add(' join LG_TESTA T on G.NUM_PROG = T.NUM_PROG ');
qt.Add(' left join ANAFORN A on A.CODKEY=T.CODICE');
qt.Add(' join OPERATORI O on T.OPERATORE = O.CODICE ');
qt.Add(' join LG_CAUSA C on T.CAUSALE = C.CODICE ');
qt.Add('where T.DATA >= :data1 and T.DATA <= :data2 ');
if CheckBox3.Checked then
qt.Add(' and T.INCASSO = :pagamento ');
if CheckBox5.Checked then
qt.Add(' and T.TERMINALE = :terminale ');
qt.Add('order by G.NUM_PROG');
FDquery3.ParamByName('data1').AsDate := Datetimepicker1.Date;
FDquery3.ParamByName('data2').AsDate := Datetimepicker2.Date;
if CheckBox3.Checked then
FDQuery3.ParamByName('pagamento').AsString := Combobox3.Items [Combobox3.Itemindex];
if CheckBox3.Checked then
FDQuery3.ParamByName('terminale').AsString := Combobox5.Items [Combobox5.Itemindex];
FDQuery3.Open;
在此选项中,您不会引入额外的切换参数,而是仅在用户选中使用它们时添加值参数。如果用户取消选中它们 - 那么您不会将它们包含在SQL文本中,因此您不会为它们分配任何值(无论如何都不会找到它们)。
5)你可以使用BETWEEN - 它可能更容易阅读。
...
where ( T.DATA BETWEEN :data1 AND :data2 )
and T.INCASSO = :pagamento
....