主頁(yè) > 知識(shí)庫(kù) > 詳解SQL Server中的數(shù)據(jù)類型

詳解SQL Server中的數(shù)據(jù)類型

熱門標(biāo)簽:安卡拉地圖標(biāo)注app 我要地圖標(biāo)注數(shù)量有限制嗎 電話機(jī)器人怎么代理商 家庭農(nóng)場(chǎng)地圖標(biāo)注名稱怎樣起名 電銷需要外呼系統(tǒng)嗎 零成本地圖標(biāo)注賺錢 千呼電話機(jī)器人可以試用嗎 400電話辦理泰安 互聯(lián)網(wǎng)電話外呼系統(tǒng)

前言

前面幾篇文章我們講解了索引有關(guān)知識(shí),這一節(jié)我們?cè)倮^續(xù)我們下面內(nèi)容講解,簡(jiǎn)短的內(nèi)容,深入的理解。

數(shù)據(jù)類型

SQL Server支持兩種字符數(shù)據(jù)類型,一種是常規(guī),另外一種則是Unicode。常規(guī)數(shù)據(jù)類型包括CHAR和VARCHAR,Unicode數(shù)據(jù)類型包括NCAHR和NVARCHAR。常規(guī)字符的每個(gè)字符使用1個(gè)字節(jié)存儲(chǔ),而Unicode數(shù)據(jù)的每個(gè)字符要求2個(gè)字節(jié)。常規(guī)字符列限制為僅僅只針對(duì)于英語(yǔ),而Unicode則是針對(duì)于多種語(yǔ)言。兩種字符數(shù)據(jù)類型的文本表示方式也不相同,在表示常規(guī)字符文本時(shí),只需要使用單引號(hào),比如'Hello,my name is JeffckyWang,I'm from cnblogs',而對(duì)于Unicode字符文本時(shí),需要指定字符N作為前綴,即N‘Hello,my name is JeffckyWang,I'm from cnblogs'。

名稱中沒有VAR元素的任何數(shù)據(jù)類型(CHAR、NCHAR)具有固定長(zhǎng)度,即SQL Server按照列定義大小保留行空間,而不是按照字符中的實(shí)際字符保留空間。比如某列定義大小為CHAR(25),則SQL Server在該行保留25個(gè)字符的空間,而不管存儲(chǔ)字符串的長(zhǎng)度。

名稱中含有VAR元素的數(shù)據(jù)類型(VARCHAR、NVARCHAR)具有可變長(zhǎng)度,即SQL Server根據(jù)存儲(chǔ)需要,在行中使用盡可能多的存儲(chǔ)空間存儲(chǔ)字符串,同時(shí)外加兩個(gè)額外的字節(jié)偏移數(shù)據(jù)。例如,如果將某列定義為VARCHAR(25),此時(shí)支持的最大字符數(shù)為25,但實(shí)際上按照字符串中實(shí)際字符確定存儲(chǔ)量。-摘抄自SQL Server 2012 T-SQL基礎(chǔ)教程。

這里關(guān)于Unicode字符數(shù)據(jù)類型我們需要重點(diǎn)理解下。我們先創(chuàng)建一個(gè)表,如下:

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

此時(shí)我們手動(dòng)插入數(shù)據(jù),正常插入,如下:

INSERT dbo.UnicodeType
  ( firstname, lastname )
VALUES ( '11111', -- firstname - varchar(5)
   N'啊的發(fā)個(gè)好' -- lastname - nvarchar(5)
   )

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

此時(shí)我們將firstname,插入五個(gè)中文試試如下:

INSERT dbo.UnicodeType
  ( firstname, lastname )
VALUES ( '達(dá)得到讓人', -- firstname - varchar(5)
   N'達(dá)得到讓人' -- lastname - nvarchar(5)
   )

此時(shí)出現(xiàn)如下結(jié)果:

也就是說(shuō)在常規(guī)字符類型如上述VARVHAR中定義為五個(gè)字符,此時(shí)我們插入五個(gè)中文字符則會(huì)被截取,當(dāng)然也插入不進(jìn)去。因?yàn)樯鲜鲆呀?jīng)明確講了1個(gè)非英語(yǔ)字符串相當(dāng)于兩個(gè)字節(jié),此時(shí)中文所占用的是十個(gè)字節(jié),而此時(shí)VARCHAR才五個(gè)字符,所以出現(xiàn)警告。我們?cè)賮?lái)將firstname插入兩個(gè)中文兩個(gè)英文或者數(shù)字看看

INSERT dbo.UnicodeType
  ( firstname, lastname )
VALUES ( '達(dá)得1', -- firstname - varchar(5)
   N'達(dá)得到讓人' -- lastname - nvarchar(5)
   )

此時(shí)插入進(jìn)去為出現(xiàn)警告,因?yàn)榇藭r(shí)兩個(gè)中文字符即四個(gè)字節(jié)加上一個(gè)數(shù)字字節(jié)剛好五個(gè)字節(jié),所以能正常插入,我們?cè)賮?lái)看看lastname,由上知,既然英文或者數(shù)字被當(dāng)做一個(gè)字節(jié),那么我們對(duì)lastname插入四個(gè)中文字符和兩個(gè)英文字節(jié)剛好十個(gè)字節(jié)應(yīng)該是好使的。我們看看:

INSERT dbo.UnicodeType
  ( firstname, lastname )
VALUES ( '達(dá)得1', -- firstname - varchar(5)
   N'達(dá)得到讓ab' -- lastname - nvarchar(5)
   )

oh,shit,此時(shí)居然出錯(cuò)了,如下:

我們上述分析的不是有理有據(jù)么,難道這里英文不是占用一個(gè)字節(jié)么,我們插入一個(gè)英文試試。

INSERT dbo.UnicodeType
  ( firstname, lastname )
VALUES ( '達(dá)得1', -- firstname - varchar(5)
   N'達(dá)得到讓b' -- lastname - nvarchar(5)
   )

結(jié)果正確了,實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn),從這里我們可以看出:在常規(guī)字符中,一個(gè)中文會(huì)當(dāng)做是兩個(gè)字節(jié)來(lái)使用,一個(gè)英文會(huì)當(dāng)做是一個(gè)字節(jié)使用,但是在Unicode中,一個(gè)中文也是會(huì)當(dāng)做兩個(gè)字節(jié)來(lái)使用,但是一個(gè)英文也會(huì)當(dāng)做是兩個(gè)字節(jié)來(lái)使用。至此我們可以得出結(jié)論,個(gè)人一直以為在Unicode中,將英文是作為一個(gè)字節(jié)存儲(chǔ),見識(shí)短啊。

常規(guī)字符和Unicode中一個(gè)中文字符用兩個(gè)字節(jié)存儲(chǔ),而對(duì)英文,常規(guī)字符用一個(gè)字節(jié)存儲(chǔ),而Unicode依然是用兩個(gè)字節(jié)存儲(chǔ)。

字符串函數(shù)

對(duì)字符串操作的函數(shù)有SUBSTRING、LEFT、RIGHT、CHARINDEX、PATINDEX、REPLACE、REPICATE、STUFF、UPPER、LOWER、RTRIM、LTRIM、FORMAT。對(duì)于簡(jiǎn)單的函數(shù)我們略過(guò),下面我們來(lái)講講幾個(gè)需要注意的地方。

LEN與DATALENGTH比較

我們首先創(chuàng)建如下測(cè)試表

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

我們插入測(cè)試數(shù)據(jù)

INSERT dbo.StringFun
  ( firststr, secondstr )
VALUES ( '我是JeffckyWang,我來(lái)自于博客園,專注于.NET技術(shù)', -- firststr - varchar(max)
   '我是JeffckyWang,我來(lái)自于博客園,專注于.NET技術(shù)' -- secondstr - text
   )

我們首先利用LEN函數(shù)來(lái)返回firststr和secondstr的字符串長(zhǎng)度大小

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

好極了,出錯(cuò)了。LEN函數(shù)無(wú)法對(duì)TEXT進(jìn)行操作。我們接著往下看。

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

此時(shí)未報(bào)錯(cuò)誤,結(jié)果顯示為47個(gè)字節(jié)大小。 既然LEN對(duì)文本無(wú)效,我們不對(duì)文本操作就是。

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

此時(shí)類型為VARCAHR的firststr字節(jié)大小卻為31,為何,看到這里我們想必恍然大悟,在上述我們講到常規(guī)字符會(huì)對(duì)中文以一個(gè)字符兩個(gè)字節(jié)大小存儲(chǔ),但是這里實(shí)際上返回的是實(shí)際字符大小,當(dāng)然一個(gè)是存儲(chǔ),一個(gè)是檢索,還是有點(diǎn)不同,同時(shí)我們也不會(huì)將中文存儲(chǔ)到VARCHAR中。到這里我們可以得出結(jié)論。

結(jié)論:DATALENGTH函數(shù)是針對(duì)于TEXT,而LEN是針對(duì)于VARCHAR,對(duì)TEXT無(wú)效會(huì)報(bào)錯(cuò)。

到這里我們還有一個(gè)特殊值未進(jìn)行處理,那就是NULL。那么問(wèn)題來(lái)了,LEN和DATALENGTH對(duì)NULL,它的長(zhǎng)度大小是多少呢,是0還是不是0尼?

是我們來(lái)測(cè)試下:

DECLARE @MyVar VARCHAR(10)
SET @MyVar = NULL
IF (LEN(@MyVar) = 0)
PRINT 'LEN of NULL is 0'
ELSE
PRINT 'LEN of NULL is NULL'

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

結(jié)論:LEN和DATALENGTH對(duì)于NULL計(jì)算的結(jié)果就是NULL。

我們?cè)賮?lái)看看二者差異的一個(gè)小地方:

SELECT LEN('JeffckyWang ') AS 'LEN'
SELECT DATALENGTH('JeffckyWang ') AS 'DATALENGTH'

結(jié)論:LEN會(huì)刪除尾隨空格,而DATALENGTH不會(huì)

CHARINDEX與PATINDEX比較

CHARINDEX和PATINDEX字符串函數(shù)都是查詢返回指定匹配字符串的開始位置。

我們先查詢一個(gè)字符串,此字符串在表中存在,如下:

USE AdventureWorks2012;
GO
SELECT CHARINDEX('Worn', DocumentSummary) AS 'CHARINDEX'
FROM Production.Document
WHERE ChangeNumber = 55;
GO
SELECT PATINDEX('Worn', DocumentSummary) AS 'PATINDEX'
FROM Production.Document
WHERE ChangeNumber = 55;

為何CHARINDEX函數(shù)查找到了,而PATINDEX沒有查詢到呢?此時(shí)就說(shuō)說(shuō)二者的區(qū)別,二者都有兩個(gè)參數(shù),第二個(gè)參數(shù)都是要匹配的字符串,但是PATINDEX函數(shù)必須在需要匹配的字符串之前或者之后添加百分號(hào)即通配符,而CHARINDEX函數(shù)則不需要。如下即可:

USE AdventureWorks2012;
GO
SELECT CHARINDEX('Worn', DocumentSummary) AS 'CHARINDEX'
FROM Production.Document
WHERE ChangeNumber = 55;
GO
SELECT PATINDEX('%Worn%', DocumentSummary) AS 'PATINDEX'
FROM Production.Document
WHERE ChangeNumber = 55;

結(jié)論:PATINDEX匹配字符串必須在字符串前面或者后面或者前后添加通配符,而CHARINDEX無(wú)需添加。

總結(jié)

本節(jié)我們主要講解了SQL中的數(shù)據(jù)類型以及幾個(gè)需要注意的地方,簡(jiǎn)短的內(nèi)容,深入的理解,我們下節(jié)再會(huì)。

以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流,同時(shí)也希望多多支持腳本之家!

您可能感興趣的文章:
  • 詳解MySQL數(shù)據(jù)類型int(M)中M的含義
  • mysql存儲(chǔ)引擎和數(shù)據(jù)類型(二)
  • Java數(shù)據(jù)類型與MySql數(shù)據(jù)類型對(duì)照表
  • SQL Server數(shù)據(jù)類型轉(zhuǎn)換方法
  • SQL Server比較常見數(shù)據(jù)類型詳解
  • SQLite教程(七):數(shù)據(jù)類型詳解
  • SQL Server數(shù)據(jù)類型char、nchar、varchar、nvarchar的區(qū)別淺析
  • sql使用cast進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換示例
  • SQL2005中char nchar varchar nvarchar數(shù)據(jù)類型的區(qū)別和使用環(huán)境講解
  • SQL的常用數(shù)據(jù)類型列表詳解

標(biāo)簽:東營(yíng) 濱州 來(lái)賓 大同 黃山 池州 新鄉(xiāng) 文山

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《詳解SQL Server中的數(shù)據(jù)類型》,本文關(guān)鍵詞  詳解,SQL,Server,中的,數(shù)據(jù),;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《詳解SQL Server中的數(shù)據(jù)類型》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于詳解SQL Server中的數(shù)據(jù)類型的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章