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.mzph.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…