SQL Server-數據類型(七)

前言

前面幾篇文章我們講解了索引有關知識,這一節我們再繼續我們下面內容講解,簡短的內容,深入的理解,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(5) NOT NULL,lastname NVARCHAR(5) NOT NULL
);

此時我們手動插入數據,正常插入,如下:

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

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

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

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

此時出現如下結果:

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

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

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

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

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

我們上述分析的不是有理有據么,難道這里英文不是占用一個字節么,我們插入一個英文試試。

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

結果正確了,實踐是檢驗真理的唯一標準,從這里我們可以看出:在常規字符中,一個中文會當做是兩個字節來使用,一個英文會當做是一個字節使用,但是在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  ( '我是JeffckyWang,我來自于博客園,專注于.NET技術', -- firststr - varchar(max)'我是JeffckyWang,我來自于博客園,專注于.NET技術'  -- secondstr - 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(10)
SET @MyVar = NULL
IF (LEN(@MyVar) = 0)
PRINT 'LEN of NULL is 0'
ELSE
PRINT 'LEN of NULL is NULL'

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

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

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

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

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

CHARINDEX與PATINDEX比較

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

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

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

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

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

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

總結

本節我們主要講解了SQL中的數據類型以及幾個需要注意的地方,簡短的內容,深入的理解,我們下節再會。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/457462.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/457462.shtml
英文地址,請注明出處:http://en.pswp.cn/news/457462.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【隨記】SQL Server連接字符串參數說明

廢話不多說,請參見 SqlConnection.ConnectionString 。 轉載于:https://www.cnblogs.com/xiesong/p/5749037.html

【設計模式 00】設計模式的六大原則

設計模式的六大原則 參考: 設計模式六大原則 1. 單一職責原則 一個類只負責一個明確的功能 優點: 降低類的復雜度,提高代碼可讀性和可維護性降低變更時對其他功能的影響 2. 里氏替換原則 **原則一:**若 o1 是 C1 的一個實例化…

pb retrieve時停止工作_大佬們掛在嘴邊的PE、PB是什么?

在緊鑼密鼓地準備科創50ETF的發行工作間隙,今天小夏先帶你讀懂最簡單的PE、PB估值指標這兩大指標。01、什么是PE(市盈率)PE,也就是市價盈利比率,簡稱市盈率。市盈率是指股票價格與每股收益(每股收益&#x…

EF CodeFirst 如何通過配置自動創建數據庫當模型改變時

最近悟出來一個道理,在這兒分享給大家:學歷代表你的過去,能力代表你的現在,學習代表你的將來。 十年河東十年河西,莫欺少年窮 學無止境,精益求精 本篇為進階篇,也是彌補自己之前沒搞明白的地方,…

對AutoIt中控件和窗口的理解

經過嘗試,對AutoIt中Control和Window有了新的認識,分享一下 1.Control 現在我想對一個WinForm架構的應用程序進行自動化操作,得到控件Advanced Mode屬性為[Name:XXX]。 然而在該窗口中有多個相同屬性的Control,而依該屬性只能操作…

【設計模式 01】簡單工廠模式(Simple factory pattern)

簡單工廠模式 可以根據參數的不同返回不同類的實例 參考: CSDN|簡單工廠模式 簡單工廠通過傳給工廠類的參數的不同,返回不同的對象,包括三部分組成: 具體的”產品“工廠類(實例化并返回”產品“)客戶端&am…

[Hadoop]MapReduce多路徑輸入與多個輸入

1. 多路徑輸入 FileInputFormat是所有使用文件作為其數據源的 InputFormat 實現的基類,它的主要作用是指出作業的輸入文件位置。因為作業的輸入被設定為一組路徑, 這對指定作業輸入提供了很強的靈活性。FileInputFormat 提供了四種靜態方法來設定 Job 的…

pvrect r語言 聚類_R語言實現KEGG通路富集可視化

用過KEGG的朋友應該都很熟悉里面的通路地圖。你是否想過如果自己可以控制通路圖將自己的基因繪制在一個通路圖中,那么今天給大家介紹一個新推出的Bioconductor軟件包pathview。這個包可以進行KEGG富集分析。首先,我們不耐煩的介紹下Bioconductor包的安裝…

【設計模式 02】策略模式( Strategy)

策略模式 參考: CSDN | 策略模式百家號 | 策略模式 如果某個系統需要不同的算法(如超市收銀的優惠算法),那么可以把這些算法獨立出來,使之之間可以相互替換,這種模式叫做策略模式,它同樣具有三個…

PL/SQL復合變量

復合變量可以將不同數據類型的多個值存儲在一個單元中。由于復合類型可以由用戶自己根據需要定義其結構,所以復合數據類型也稱為自定義數據類型。在PL/SQL中,使用%TYPE聲明的變量類型與數據表中字段的數據類型相同,當數據表中字段數據類型修改…

Android中使用am命令實現在命令行啟動程序詳解

在Android中,除了從界面上啟動程序之外,還可以從命令行啟動程序,使用的是命令行工具am. 復制代碼代碼如下:usage: am [subcommand] [options] start an Activity: am start [-D] -D: enable debugging send a broadcast Intent: am br…

用Visual Studio 2019連接 WSL來編譯調試C/C++項目

因為有作業要在Linux環境下寫,用虛擬機直接卡成PPT,VS code又不會調試,就搞一下VS 2019吧。 環境 windows 10 WSL(Ubuntu 18.04.4) Visual Studio Community 2019 Linux 里要有C/C環境(gcc等)VS要有 適用于 Linux…

node.js Websocket消息推送---GoEasy

Goeasy, 它是一款第三方推送服務平臺,使用它的API可以輕松搞定實時推送!個人感覺goeasy推送更穩定,推送速度快,代碼簡單易懂上手快瀏覽器兼容性:GoEasy推送支持websocket 和polling兩種連接方式,從而可以支…

git 移動分支指針_理解git 中的HEAD指針branch指針

HEAD指針使用git checkout 來移動HEAD指針,移動的對象可以是分支指針也可以是快照。HEAD指針可以指向快照也可以指向branch。當指向branch時提交后會和branch指針一起向后移動,當不指向branch提交時時則會在一個detached狀態。分支(branch)指針使用git b…

應用程序域

好文鏈接 使用.NET建立的可執行程序 .exe,并沒有直接承載到進程當中,而是承載到應用程序域(AppDomain)當中。應用程序域是.NET引入的一個新概念,它比進程所占用的資源要少,可以被看作是一個輕量級的進程。 …

【設計模式 03】裝飾模式——俄羅斯套娃?

裝飾模式(俄羅斯套娃?) 裝飾模式:動態的給某些對象添加額外的功能 參考: 簡書 | 裝飾模式 博客園 | 簡說設計模式——裝飾模式 博客園 | 裝飾器模式 Decorator 結構型 設計模式 (十) 什么是裝飾模式 裝飾模式也叫裝飾器模式,p…

系統移植的四大步驟

最近在學習系統移植的相關知識,在學習和調試過程中,發現了很多問題,也解決了很多問題,但總是對于我們的開發結果有一種莫名其妙的感覺,糾其原因,主要對于我們的開發環境沒有一個深刻的認識,有時…

bem什么意思_bem是什么意思_bem的翻譯_音標_讀音_用法_例句_愛詞霸在線詞典

全部Methods Three different concentrations of the n - butanol extract of MOH ( BEM ) : 0.038 g L ~ ( - 1 ), 0.11 g L ~ ( - 1 ) and 0.34 g L ~ ( - 1 ) were prepared.巴戟天醇提取物 ( BEM ) 配成含生藥0.038gL~ ( -1)、0.11gL~ ( -1 ) 、 0.34gL~ ( -1 ) 三種濃度…

display:flex

flex:彈性布局 常用屬性介紹: flex-direction: column (設置主容器主軸方向) flex-flow: row wrap (第一個參數為flex-direction,第二個為flex-wrap) align-items: flex-start (設…

Linux(Ubuntu 19.10)下 Qt5 連接 MySQL(QMYSQL driver not loaded)

Linux(Ubuntu 19.10)下 Qt5 連接 MySQL 安裝好 MySQL 和 Qt Qt 連接 MySQL 的代碼 QSqlDatabase dQSqlDatabase::addDatabase("QMYSQL");//加載mysql驅動,這個字符串是固定的 d.setHostName("127.0.0.1"); d.setDatabas…