SQL Server-資料型別

25minutes發表於2021-09-09

前言

前面幾篇文章我們講解了索引有關知識,這一節我們再繼續我們下面內容講解,簡短的內容,深入的理解,Always to review the basics。

資料型別

SQL Server支援兩種字元資料型別,一種是常規,另外一種則是Unicode。常規資料型別包括CHAR和VARCHAR,Unicode資料型別包括NCAHR和NVARCHAR。常規字元的每個字元使用1個位元組儲存,而Unicode資料的每個字元要求2個位元組。常規字元列限制為僅僅只針對於英語,而Unicode則是針對於多種語言。兩種字元資料型別的文字表示方式也不相同,在表示常規字元文字時,只需要使用單引號,比如'Hello,my name is JeffckyWang,I'm from cnblogs',而對於Unicode字元文字時,需要指定字元N作為字首,即N‘Hello,my name is JeffckyWang,I'm from cnblogs’。

名稱中沒有VAR元素的任何資料型別(CHAR、NCHAR)具有固定長度,即SQL Server按照列定義大小保留行空間,而不是按照字元中的實際字元保留空間。比如某列定義大小為CHAR(25),則SQL Server在該行保留25個字元的空間,而不管儲存字串的長度。

名稱中含有VAR元素的資料型別(VARCHAR、NVARCHAR)具有可變長度,即SQL Server根據儲存需要,在行中使用盡可能多的儲存空間儲存字串,同時外加兩個額外的位元組偏移資料。例如,如果將某列定義為VARCHAR(25),此時支援的最大字元數為25,但實際上按照字串中實際字元確定儲存量。-摘抄自SQL Server 2012 T-SQL基礎教程。

這裡關於Unicode字元資料型別我們需要重點理解下。我們先建立一個表,如下:

CREATE TABLE UnicodeType( firstname VARCHAR() NOT NULL, lastname NVARCHAR() NOT NULL);

此時我們手動插入資料,正常插入,如下:

INSERT dbo.UnicodeType        ( firstname, lastname )VALUES  ( )          N)          )

字元都完全插入表中,如下:

圖片描述

此時我們將firstname,插入五個中文試試如下:

INSERT dbo.UnicodeType        ( firstname, lastname )VALUES  ( )          N)          )

此時出現如下結果:

圖片描述

也就是說在常規字元型別如上述VARVHAR中定義為五個字元,此時我們插入五個中文字元則會被擷取,當然也插入不進去。因為上述已經明確講了1個非英語字串相當於兩個位元組,此時中文所佔用的是十個位元組,而此時VARCHAR才五個字元,所以出現警告。我們再來將firstname插入兩個中文兩個英文或者數字看看

INSERT dbo.UnicodeType        ( firstname, lastname )VALUES  ( )          N)          )

此時插入進去為出現警告,因為此時兩個中文字元即四個位元組加上一個數字位元組剛好五個位元組,所以能正常插入,我們再來看看lastname,由上知,既然英文或者數字被當做一個位元組,那麼我們對lastname插入四個中文字元和兩個英文位元組剛好十個位元組應該是好使的。我們看看:

INSERT dbo.UnicodeType        ( firstname, lastname )VALUES  ( )          N)          )

oh,shit,此時居然出錯了,如下:

圖片描述

我們上述分析的不是有理有據麼,難道這裡英文不是佔用一個位元組麼,我們插入一個英文試試。

INSERT dbo.UnicodeType        ( firstname, lastname )VALUES  ( )          N)          )

結果正確了,實踐是檢驗真理的唯一標準,從這裡我們可以看出:在常規字元中,一箇中文會當做是兩個位元組來使用,一個英文會當做是一個位元組使用,但是在Unicode中,一箇中文會當做兩個位元組來使用,但是一個英文也會當做是兩個位元組來使用。至此我們可以得出結論,個人一直以為在Unicode中,將英文是作為一個位元組儲存,見識短啊。

常規字元和Unicode中一箇中文字元用兩個位元組儲存,而對英文,常規字元用一個位元組儲存,而Unicode依然是用兩個位元組儲存。

字串函式

對字串操作的函式有SUBSTRING、LEFT、RIGHT、CHARINDEX、PATINDEX、REPLACE、REPICATE、STUFF、UPPER、LOWER、RTRIM、LTRIM、FORMAT。對於簡單的函式我們略過,下面我們來講講幾個需要注意的地方。

LEN與DATALENGTH比較

我們首先建立如下測試表

CREATE TABLE StringFun(    firststr VARCHAR(max) NOT NULL,    secondstr TEXT NOT NULL);

我們插入測試資料

INSERT dbo.StringFun        ( firststr, secondstr )VALUES  (  varchar(max)           text          )

我們首先利用LEN函式來返回firststr和secondstr的字串長度大小

SELECT LEN(firststr) AS VARCAHRFieldSize FROM dbo.StringFunSELECT LEN(secondstr) AS TEXTFieldSize FROM dbo.StringFun

圖片描述

好極了,出錯了。LEN函式無法對TEXT進行操作。我們接著往下看。

SELECT DATALENGTH(firststr) AS VARCAHRFieldSize FROM dbo.StringFunSELECT DATALENGTH(secondstr) AS TEXTFieldSize FROM dbo.StringFun

圖片描述

此時未報錯誤,結果顯示為47個位元組大小。 既然LEN對文字無效,我們不對文字操作就是。

SELECT LEN(firststr) AS VARCAHRFieldSize FROM dbo.StringFunSELECT DATALENGTH(secondstr) AS TEXTFieldSize FROM dbo.StringFun

圖片描述

此時型別為VARCAHR的firststr位元組大小卻為31,為何,看到這裡我們想必恍然大悟,在上述我們講到常規字元會對中文以一個字元兩個位元組大小儲存,但是這裡實際上返回的是實際字元大小,當然一個是儲存,一個是檢索,還是有點不同,同時我們也不會將中文儲存到VARCHAR中。到這裡我們可以得出結論。

結論:DATALENGTH函式是針對於TEXT,而LEN是針對於VARCHAR,對TEXT無效會報錯。

到這裡我們還有一個特殊值未進行處理,那就是NULL。那麼問題來了,LEN和DATALENGTH對NULL,它的長度大小是多少呢,是0還是不是0尼?

是我們來測試下:

圖片描述

DECLARE @MyVar VARCHAR()SET @MyVar = NULLIF (LEN(@MyVar) = )PRINT ELSEPRINT '

圖片描述

圖片描述

我們上述得到的結果是LEN of NULL is NULL,DATALENGTH就不再演示了。

結論:LEN和DATALENGTH對於NULL計算的結果就是NULL。

我們再來看看二者差異的一個小地方:

SELECT LEN(SELECT DATALENGTH('

圖片描述

結論:LEN會刪除尾隨空格,而DATALENGTH不會

CHARINDEX與PATINDEX比較

CHARINDEX和PATINDEX字串函式都是查詢返回指定匹配字串的開始位置。

我們先查詢一個字串,此字串在表中存在,如下:

圖片描述

USE AdventureWorks2012;GOSELECT CHARINDEX(FROM Production.DocumentWHERE ChangeNumber = ;GOSELECT PATINDEX(FROM Production.DocumentWHERE ChangeNumber = 55;

圖片描述

圖片描述

為何CHARINDEX函式查詢到了,而PATINDEX沒有查詢到呢?此時就說說二者的區別,二者都有兩個引數,第二個引數都是要匹配的字串,但是PATINDEX函式必須在需要匹配的字串之前或者之後新增百分號即萬用字元,而CHARINDEX函式則不需要。如下即可:

圖片描述

USE AdventureWorks2012;GOSELECT CHARINDEX(FROM Production.DocumentWHERE ChangeNumber = ;GOSELECT PATINDEX(FROM Production.DocumentWHERE ChangeNumber = 55;

圖片描述

圖片描述

結論:PATINDEX匹配字串必須在字串前面或者後面或者前後新增萬用字元,而CHARINDEX無需新增。



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4328/viewspace-2800079/,如需轉載,請註明出處,否則將追究法律責任。

相關文章