本文轉載自【微信公眾號:五角錢的程式設計師,ID:xianglin965】經微信公眾號授權轉載,如需轉載與原文作者聯繫
程式設計師在編程過程中,經常會在代碼中使用到「where 1=1」,這是為什麼呢?
SQL注入
初次看到這種寫法的同學肯定很納悶,加不加where 1=1,查詢不都一樣嗎?例如:
select *from customers;與select *from customerswhere 1=1;
查詢出來的結果完全沒有區別呀。
是的,上面的查詢結果是沒有區別,但是這並不是我們要添加它的目的。我們知道1=1表示true,即永真,在SQL注入時配合or運算符會得到意向不到的結果。
例如,當我們要刪除客戶名稱為「張三」的記錄,我們可以這樣寫:
delete from customerswhere name='張三'
這個時候如果在where語句後面加上 or 1=1會是什麼後果?
即:
delete from customerswhere name='張三' or 1=1
本來只要刪除張三的記錄,結果因為添加了or 1=1的永真條件,會導致整張表裡的記錄都被刪除了。
當然這種事我們可千萬不能幹,也不能讓別人有機可乘,這裡只是為了表述where 1=1的作用之一。
語法規範
我們在寫代碼的過程中,為了保證語法規範的時候,也會使用到where 1=1。
我們先看下面這段Java代碼:
String sql="select *from table_namewhere 1=1";if( condition 1) {sql=sql+" and var2=value2";}if(condition 2) { sql=sql+" and var3=value3";}
如果我們不寫1=1的話,當condition 1為真時,代碼拼接後被執行的SQL代碼如下:
select *from table_namewhere and var2=value2;
很明顯,這裡會出現一個SQL 的語法錯誤:and必須前後都有條件。
有人說我直接把where寫在if語句裡面,我就不寫where 1=1。
String sql="select *from table_name";if( condition 1) {sql=sql+" where var2=value2";}if(condition 2) { sql=sql+" where var3=value3";}
當condition 1為真,condition 2為假時,上面被執行的SQL代碼為:
select *from table_namewhere var2=value2;
這個確實沒有語法錯誤,但是當condition 1和condition 2都為真呢?那麼SQL語句就變成了這樣:
select *from table_namewhere var2=value2where var3=value3;
很明顯這是不符合SQL語法規範的。
這裡寫上where 1=1 是為了避免where 關鍵字後面的第一個詞直接就是 「and」而導致語法錯誤,加上1=1後,不管後面有沒有and條件都不會造成語法錯誤了。
拷貝表
在我們進行數據備份時,也經常使用到where 1=1,當然其實這兩可以不寫,寫上之後如果想過濾一些數據再備份會比較方便,直接在後面添加and條件即可。
create table table_nameas select *from Source_tablewhere 1=1;
複製表結構
有1=1就會有1<>1或1=2之類的永假的條件,這個在拷貝表的時候,加上where 1<>1,意思就是沒有任何一條記錄符合條件,這樣我們就可以只拷貝表結構,不拷貝數據了。
create table table_nameas select *from Source_tablewhere 1 <>1;
1=1的壞處
我們在寫SQL時,加上了1=1後雖然可以保證語法不會出錯!
select * from table where 1=1
但是因為table中根本就沒有名稱為1的欄位,該SQL其實等效於select * from table,這個SQL語句很明顯是全表掃描,需要大量的IO操作,數據量越大越慢。
所以在查詢時,where1=1的後面需要增加其它條件,並且給這些條件建立適當的索引,效率就會大大提高。
結束!