報表衆多的系統,不僅僅是where子句存在拼接,join子句也可能需要拼接。還是看代碼:
String sql=" select * from bill ";
if (queryParams.pTypeId != null)
{
dbHelper.AddParameter("@ptypeid", ptypeid);
sqlWhere += " and p.typeid like @ptypeid ";
sqlJoin += " inner join ptype p on a.ptypeid = p.id ";
}
if (queryParams.eTypeId != null)
{
dbHelper.AddParameter("@etypeid", etypeid);
sqlWhere += " and e.typeid like @etypeid ";
sqlJoin += " inner join employee e on a.etypeid = e.id";
}
if (queryParams.kTypeId != null)
{
dbHelper.AddParameter("@ktypeid", ktypeid);
sqlWhere += " and k.typeid like @ktypeid ";
sqlJoin += " left join stock k on a.ktypeid = k.id ";
}
新代碼:
String sql=@"
select * from bill
inner join ptype p on @enablePtypeJoin and a.ptypeid = p.id and a.profileid = p.profileid
inner join employee e on @enableEtypeJoin and a.etypeid = e.id and a.profileid = e.profileid
left join stock k on @enableKtypeJoin and a.ktypeid = k.id
where
and (@enablePtypeJoin and p.typeid like @ptypeid )
and (@enableEtypeJoin and e.typeid like @etypeid )
and (@enableKtypeJoin and p.typeid like @ktypeid )
";
dbHelper.AddParameter("@ptypeid", ptypeid );
dbHelper.AddParameter("@etypeid", etypeid);
dbHelper.AddParameter("@ktypeid", ktypeid);
dbHelper.AddParameter("@enablePtypeJoin",ptypeid != null);
dbHelper.AddParameter("@enableKtypeJoin",ktypeid != null);
dbHelper.AddParameter("@enableEtypeJoin",etypeid != null);
新代碼的特點是採用了@EnableXXX型的bool值插入了join子句和Where子句內。
比如 (@enablePtypeJoin and p.typeid like @ptypeid ),當enablePtypeJoin 爲false 的時候,p.typeid like @ptypeid就等於沒有拼接進來一樣,當enablePtypeJoin 爲 true 的時候,@enablePtypeJoin=true也是沒用的。從而通過這個@EnableXXX達到和拼接一樣的效果。
通過 mysql 的explain可以看到:採用@enableXXX的方法可能會降低效能。不過需要實際測試才知道。因爲,即使 @enablePtypeJoin=false,連接也還是發生了。同樣的語句,在在sqlserver中,從執行計劃上可以看出, @enablePtypeJoin=false的時候,join不會發生,故而不會降低效能。
新代碼其實是僞代碼,因爲在sqlserver內,並沒有bool類型。通常會用1=1 和1=0表達true/false,因此,
dbHelper.AddParameter("@enablePtypeJoin",ptypeid != null);
必須做出修改,適應這個情況:
dbHelper.AddParameter("@enablePtypeJoin",ptypeid != null?1:0);
對應的:
and (@enablePtypeJoin and p.typeid like @ptypeid )
需要改成:
and (1=@enablePtypeJoin and p.typeid like @ptypeid )
閱讀效果稍微差了一點,帶上比起原來的代碼好要的多了。