對sql語句也要有敬畏之心

2021-09-05 09:40:46 字數 1356 閱讀 6216

在上個月,在幫同事解決bug的時候,我人生中第一次看到了對datetime型別的字段做like查詢的sql語句…

這是一條很簡單的語句,查詢某個月某個使用者的簽到記錄

select 

*from

***x

where

uid = #

and

sign_date like concat('%',#,'%')

不得不說,當我看到這段sql的時候,我蒙蔽了,在我的認知裡,我們一直以為只有文字才可以使用like的, 沒想到datetime型別也可以使用?

我們來分析一下這一小段糟點滿滿的sql:

0.簽到日期使用datetime型別,明顯應該使用date

1.使用了like模糊查詢,首先明確一點,like確實是只有對文字型別的資料才可以使用的。那這裡為什麼datetime型別也可以使用呢,答案就是mysql會任勞任怨的把每一條庫里的記錄由datetime型別轉化為對應的字串型別,然後再和模糊查詢的條件去一一匹配,嗯,你必須承認這條sql完成了需求。但是這個效率直接**,mysql要將每行datetime型別資料轉化為字串型別資料,然後再去匹配,效率非常低,索引直接失效。對於datetime型別,使用between或者》=,<=月初月尾日期來實現,都會走索引的。

2.在使用like模糊查詢時,不管三七二十一直接就使用前字尾匹配,這也是不允許的。在使用like模糊查詢中,如果是能使用字首匹配的時候盡量使用字首匹配,這樣當該列有索引的時候,可以走索引。

這是一條很簡單的語句,但是不得不說寫的非常的糟糕,完全沒有考慮過效能,只是為了完成需求而已。

我們編寫sql語句一定要考慮效能,要充分利用索引,盡可能的編寫好的**。

另外,我還發現,對時間型別的字段使用like,只有在讀的時候才會生效,mysql會默默把時間型別的字段轉為字串型別,然後進行模糊匹配。但是在寫的時候呢,mysql拒絕幫我們做轉換,丟擲異常,大家有興趣的時候可以試一下。我google了很久,試圖找到只支援這樣讀而不支援這樣寫的原因,但是並沒有找到具體的解釋,只能說mysql目前並沒有提供這樣的支援,但是也沒太大所謂了,沒人會這樣用的,千萬不要這樣用。

update 

***x

from

***x

where

uid = #

and

sign_date like concat('%',#,'%')

丟擲異常

error: incorrect datetime value

SQL語句 簡述對SQL注入的認識

官方的說法為 所謂sql注入,就是通過把sql命令插入到web表單提交或輸入網域名稱或頁面請求的查詢字串,最終達到欺騙伺服器執行惡意的sql命令。即把惡意的 sql 語句插入到輸入引數中,然後通過在後台 sql 伺服器上解析 執行進行的攻擊,它目前黑客對資料庫進行攻擊的最常用手段之一。通俗點說,一般...

對access執行帶引數的sql語句

oledbcommand cmd new oledbcommand string conn1 lyy.dbutility.dbhelperoledb.connectionstring oledbconnection con new oledbconnection conn1 cmd.connecti...

SQL語句對非int型資料排序

對於varchar型資料直接排序排序會出現以下問題 1 轉化成int select 卡號,姓名,部門,當前區域 from v personnel inwell where 入井時間 is not null order by convert int,卡號 2 前面補0,然後排序 select from...