某DBA在查看自己的數(shù)庫日志的時候,看到了數(shù)據庫服務器上出現(xiàn)了很多很怪異的SQL的Where條件語句,是下面這個樣子:(所有的where語句前都有了一個叫“1=1”的子條件)呵呵。
要理解這個事情的原因其實并不難。只要你是一個編寫數(shù)據庫的程序員,你就會知道——動態(tài)生成where后的條件的“麻煩”,那就是條件的“分隔”-and或or。下面聽我慢慢說來。
我們知道,大多數(shù)的查詢表單都需要用戶輸出一堆查詢條件,然后我們的程序在后臺要把這些子條件用and組合起來。于是,把and加在各個條件的中間就成為了一件“難事”,因為你的程序需要判斷:
- 如果沒有條件的話,則不需要where
- 如果只有一個條件的話,不需要and.
- 如果有多個條件的話,
- 如果and是持續(xù)加在每個條件后面的話,那么就要判斷是否是最后一個條件,因為最后一個不能加and.
- 同樣,如果and是要加在每個條件前面的話,你就需要判斷是否是第一個,如果是,那就不加。
真是TMD太煩了,所以,編程“大拿”引入了“1=1”條件語句。于是,編程的難度大幅度下降,你可以用單一的方式來處理這若干的查詢子條件了。而1=1應該會被數(shù)據庫引擎優(yōu)化時給去掉了。
1 | <pre><code> $query = "SELECT name FROM table WHERE 1=1 " ; |
3 | foreach ( $clauses as $key => $value ){ |
4 | $query .= " AND " .escape( $key ). "=" .escape( $value ). " " ; |
呵呵,DBA怎么能夠理解我們瘋狂程序員的用心良苦啊。
另外,在這里說一下,這樣的做法看似很愚蠢,但很有效,在PHP的世界中,也有人使用下面這樣的做法——使用了PHP的implode函數(shù)。
08 | function construct_sql( $base , $logic , $clauses , $suffix = '' ) |
14 | foreach ( $clauses as $key => $value ) |
15 | $queries [] = "`" . escape( $key ) . "`='" . escape( $value ) . "'" ; |
18 | $query .= " " . implode( " $logic " , $queries ) . " " . $suffix . ";" ; |
29 | return mysql_real_escape_string( $str ); |
于是,我們可以這樣使用:(為什么我們要在update語句后加上“Limit 1”呢?這個關系到性能問題,關于這方面的話題,你可以查看本站的《MySQL性能優(yōu)化的最佳20+條經驗》
)
01 | <pre><code> $updates = array ( |
09 | echo construct_sql(construct_sql( "UPDATE table SET" , ", " , $updates ) . " WHERE " , " AND " , $wheres ), "LIMIT 1" ); |
下面是輸出結果:
1 | UPDATE table SET `field1`= 'val1' , `field2`= 'val2' WHERE `field1`= 'cond1' AND `field2`= 'cond2' LIMIT 1; |
(全文完)
陳皓 編程語言, 軼事趣聞 Database, PHP, SQL