要實現這種動態的SQL語句拼裝,我們可以在宿主語言中建立一個字符串,然後逐個判斷各個復選框是否選中來向這個字符串中添加SQL語句片段。 這裡有一個問題就是當有復選框被選中的時候SQL語句是含有WHERE子句的, 而當所有的復選框都沒有被選中的時候就沒有WHERE子句了,因此在添加每一個過濾條件判斷的時候都要判斷是否已經存在WHERE語句了,如果沒有WHERE語句則添加WHERE語句。 在判斷每一個復選框的時候都要去判斷, 這使得用起來非常麻煩,因此開發人員想到了一個捷徑:為SQL語句指定一個永遠為真的條件語句(比如“1=1”),這樣就不用考慮WHERE語句是否存在的問題了。偽代碼如下:
String sql = " SELECT * FROM T_Employee WHERE 1=1"; if(工號復選框選中) { sql.appendLine("AND FNumber BETWEEN ' "+工號文本框1內容+" ' AND ' "+工號 文本框2內容+" ' "); } if(姓名復選框選中) { sql.appendLine("AND FName LIKE '%"+姓名文本框內容+"%'"); } if(年齡復選框選中) { sql.appendLine("AND FAge BETWEEN ' "+年齡文本框1內容+" 'AND' "+年齡文本框2 內容+" ' "); } executeSQL(sql);
但是使用添加了“1=1”的過濾條件以後數據庫系統就無法使用索引等查詢優化策略,數據庫系統將會被迫對每行數據進行掃描(也就是全表掃描)以比較此行是否滿足過濾條件,當表中數據量比較大的時候查詢速度會非常慢。
另外一種方法:
private void doQuery() { Bool hasWhere = false; StringBuilder sql = new StringBuilder(" SELECT * FROM T_Employee"); if(工號復選框選中) { hasWhere = appendWhereIfNeed(sql, hasWhere); sql.appendLine("FNumber BETWEEN '"+工號文本框1內容+"' AND '"+工號 文本框2內容+"'"); } if(姓名復選框選中) { hasWhere = appendWhereIfNeed(sql, hasWhere); sql.appendLine("FName LIKE '%"+姓名文本框內容+"%'"); } if(年齡復選框選中) { hasWhere = appendWhereIfNeed(sql, hasWhere); sql.appendLine("FAge BETWEEN "+年齡文本框1內容+" AND "+年齡文本框2 內容); } executeSQL(sql); } private Bool appendWhereIfNeed(StringBuilder sql,Bool hasWhere) { if(hasWhere==false) { sql. appendLine("WHERE"); } else { sql. appendLine("AND"); } }