当前位置:Gxlcms > 数据库问题 > SQL Server数据类型(七)

SQL Server数据类型(七)

时间:2021-07-01 10:21:17 帮助过:10人阅读

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.StringFun

SELECT LEN(secondstr) AS TEXTFieldSize 
FROM dbo.StringFun

技术分享

好极了,出错了。LEN函数无法对TEXT进行操作。我们接着往下看。

SELECT DATALENGTH(firststr) AS VARCAHRFieldSize 
FROM dbo.StringFun

SELECT DATALENGTH(secondstr) AS TEXTFieldSize 
FROM dbo.StringFun

技术分享

此时未报错误,结果显示为47个字节大小。 既然LEN对文本无效,我们不对文本操作就是。

SELECT LEN(firststr) AS VARCAHRFieldSize 
FROM dbo.StringFun

SELECT DATALENGTH(secondstr) AS TEXTFieldSize 
FROM dbo.StringFun

技术分享

此时类型为VARCAHR的firststr字节大小却为31,为何,看到这里我们想必恍然大悟,在上述我们讲到常规字符会对中文以一个字符两个字节大小存储,但是这里实际上返回的是实际字符大小,当然一个是存储,一个是检索,还是有点不同,同时我们也不会将中文存储到VARCHAR中。到这里我们可以得出结论。

结论:DATALENGTH函数是针对于TEXT,而LEN是针对于VARVHAR,对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。

CHARINDEX与PATINDEX比较

CHARINDEX和PATINDEX字符串函数都是查询返回指定匹配字符串的开始位置。

我们先查询一个字符串,此字符串在表中存在,如下:

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函数查找到了,而PATINDEX没有查询到呢?此时就说说二者的区别,二者都有两个参数,第二个参数都是要匹配的字符串,但是PATINDEX函数必须在需要匹配的字符串之前或者之后添加百分号即通配符,而CHARINDEX函数则不需要。如下即可:

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;

技术分享

结论:PATINDEX匹配字符串必须在字符串前面或者后面或者前后添加通配符,而CHARINDEX无需添加。

总结

本节我们主要讲解了SQL中的数据类型以及几个需要注意的地方,简短的内容,深入的理解,我们下节再会。

SQL Server数据类型(七)

标签:长度   理解   无法   int   使用   style   substring   英语   product   

人气教程排行