在關(guān)系型數(shù)據(jù)庫(kù)的世界中,無(wú)值和NULL值的區(qū)別是什么?一直被這個(gè)問(wèn)題困擾著,甚至在寫(xiě)TSQL腳本時(shí),心有戚戚焉,害怕因?yàn)樽约旱囊恢虢?,挖了坑,貽害后來(lái)人,于是,本著上下求索,不達(dá)通幽不罷休的決心(開(kāi)個(gè)玩笑),遂有此文。

學(xué)習(xí)過(guò)關(guān)系型數(shù)據(jù)庫(kù)的伙伴都知道,NULL是指不確定的值,在數(shù)據(jù)庫(kù)中絕對(duì)是噩夢(mèng)的存在;而空值,一般對(duì)字符串類(lèi)型而言,指沒(méi)有任何值的字符串類(lèi)型,為字符類(lèi)型的變量設(shè)置為空值:set @vs='',空值跟無(wú)值不同。有人可能會(huì)問(wèn),無(wú)值是什么?無(wú)值,是指數(shù)據(jù)表中沒(méi)有任何數(shù)據(jù)。無(wú)值和不確定值,單從字面意思上來(lái)看,兩者之間的定義很清楚,一旦深究,這兩者之間的關(guān)系,有時(shí)令人十分迷惑(confused),這是因?yàn)?,在特定條件下,無(wú)值會(huì)轉(zhuǎn)換為NULL值。

一,舉個(gè)栗子,理解無(wú)值和NULL值的區(qū)別

比如,創(chuàng)建一個(gè)臨時(shí)表,在不插入任何數(shù)據(jù)時(shí),該數(shù)據(jù)表是空的,沒(méi)有任何值,對(duì)其執(zhí)行select命令,將不會(huì)返回任何數(shù)據(jù)值:

create table #temp(
id int null)

創(chuàng)建一個(gè)標(biāo)量類(lèi)型的變量,在不初始化時(shí),該變量的值是不確定的,其值是NULL:

declare @vs int

創(chuàng)建一個(gè)表類(lèi)型變量,在不初始化時(shí),該表變量沒(méi)有任何數(shù)據(jù),是無(wú)值的:

declare @vt as table(
id int null)

總結(jié)一下,聲明一個(gè)標(biāo)量型變量,如果沒(méi)有對(duì)變量進(jìn)行初始化,其值是不確定的,是NULL值;對(duì)于表變量,臨時(shí)表和基礎(chǔ)表,如果沒(méi)有插入任何數(shù)據(jù),該表沒(méi)有任何數(shù)據(jù),是無(wú)值的。

二,無(wú)值和NULL值的轉(zhuǎn)換

在開(kāi)始本節(jié)之前,先為變量賦值,簡(jiǎn)單的一個(gè)select命令就可以完成變量的賦值:

select @vs=1

有些朋友思維比較活躍,立馬會(huì)想到:“用select命令可以從表中取值為變量賦值”,對(duì),但是,賦值方法不是我求索的重點(diǎn),我關(guān)注的是從表中取值為變量賦值的結(jié)果。

1,從空表中為變量賦值

如果數(shù)據(jù)表是空表,沒(méi)有任何值,那么數(shù)據(jù)庫(kù)引擎不會(huì)執(zhí)行賦值語(yǔ)句,變量保持原有值不變:

  #

但是,如果采用以下方式,那么數(shù)據(jù)庫(kù)引擎會(huì)執(zhí)行賦值語(yǔ)句,由于空表不返回任何值,數(shù)據(jù)