警惕SQL語句陷井

2021-09-06 19:37:35 字數 1537 閱讀 9712

以下sql段,大家認為結果是什麼呢?

declare @a varchar(50)

set @a='zuowenjun.cn'

select top 1 @a=isnull(fieldname,'default') from tablename where 1=2

print @a

go

可能大家都認為結果顯示是:default,因為變數@a初始化為:zuowenjun.cn,在執行sql查詢後,由於條件1=2不成立,所以查詢結果fieldname的值應該是null,然後再執行isnull函式,就會將預設值default賦給變數@a,然後最終列印是default,但實際執行的結果卻並不是這樣,而是zuowenjun.cn,原因是什麼呢?經過我的分析,找到了問題的原因,那就是select語句,在找不到的記錄的情況下,是不會執行賦值操作的(即:isnull(fieldname,'default')根本沒有執行),所以才會得出該結果,若要解決這個問題,我們可以使用set關鍵字給變理賦值,如下改良過後sql段:

declare @a varchar(50)

set @a='zuowenjun.cn'

set @a=isnull((select top 1 fieldname from tablename where 1=2),'default')

print @a

go

這樣執行的結果就是default,但這樣存在侷限性,因為set只支援單個變數賦值,那同時給多個變數賦值則無法適用,所以如果需要給多個變數同時賦值的情況,我們可以採用如下方法,雖然有點複雜,但不影響執行效率:

declare @a varchar(50),@b varchar(50)

set @a='zuowenjun.cn'

set @b='***x'

select @a=isnull(fieldname1,'default1'),@b=isnull(fieldname2,'default2')

from

(select 1 as f1) t1 left join

(select top 1 fieldname1,fieldname2,1 as f1

from tablename where 1=2) t2

on t1.f1=t2.f1

print @a + '--' + @b

go

說一下原理,因為(select 1 as f1)始終返回一條記錄1,然後用這個表t1左連線我們要查詢的sql語句 t2,1 as f1這個是必需的,因為關聯需要用到,根據左連線的原則,左表不論右邊是符合關聯條件,都會返回記錄,所以最外層的select是一定有值,fieldname1與fieldname2這時都是null,執行isnull函式自然就得到了預設值。

當然以上情形是用在sql查詢語句可能存在不符合查詢條件的情況,若確定能返回值,則沒有必要這樣做,或者即使存在不符合的情況,也可以通過後續邏輯判斷來重新給變數賦值達到相同的效果,只是要寫的語句就多些。

SQL語句 limit 語句

select from table limit offset,rows rows offset offset 在我們使用查詢語句的時候,經常要返回前幾條或者中間某幾行資料,這個時候怎麼辦呢?不用擔心,mysql 已經為我們提供了上面這樣乙個功能。limit 子句可以被用於強制 select 語句返回...

SQL語句 UPDATE語句

update students set sname abcd gender 1 where sid 1 update students,students2 set students.sname students2.sname,students.gender students2.gender wher...

SQL語句 DCL語句

目錄 資料控制語言 查詢使用者 建立使用者 刪除使用者 修改使用者密碼 忘記管理員使用者密碼解決辦法 檢視許可權 給使用者授權 撤銷授權 管理使用者,對使用者授權的操作,即資料控制語言,用來定義資料庫的訪問許可權和安全級別,及建立使用者。主要包括建立使用者 給使用者授權 對使用者撤銷授權 查詢使用者...