1、char、varchar、 nchar、 nvarchar 的区别
(1)定义:
char:固定长度,存储ANSI字符,不足的补英文半角空格。
nchar:固定长度,存储Unicode字符,不足的补英文半角空格
varchar:可变长度,存储ANSI字符,根据数据长度自动变化。
nvarchar:可变长度,存储Unicode字符,根据数据长度自动变化。
nvarchar(n) :包含n个字符的可变长度Unicode字符数据。n的值必须介于1与4,000之间。字节的存储大小是所输入字符个数的两倍。所输入的数据字符长度可以为零。
varchar[(n)]:长度为n个字节的可变长度且非Unicode 的字符数据。n必须是一个介于1和8,000 之间的数值。存储大小为输入数据的字节的实际长度,而不是n个字节。所输入的数据字符长度可以为零。
注意:ANSI 主要是以单字节来存储数据,一般适合英文。而我们常用的汉字需要用两个字节来存储,所以就要使用unicode的数据类型,不然读取出来的数据可能会乱码。
(2)区别:
①从存储方式上,nvarchar 是按字符存储的,而varchar 是按字节存储的;
②从存储量上考虑,varchar 比较节省空间,因为存储大小为字节的实际长度,而nvarchar 是双字节存储;
③在使用上,如果存储内容都是英文字符而没有汉字等其他语言符号,建议使用varchar;含有汉字的使用nvarchar,因为nvarchar是使用Unicode编码,即统一的字符编码标准,会减少乱码的出现几率;
④如果你做的项目可能涉及不同语言之间的转换, 建议用nvarchar。
(3)优缺点:
nvarchar优点:判断字符串的时候可以不需要考虑中英文两种字符的差别,可以避免程序中乱码的问题。
nvarchar缺点:存储英文字符会增大一倍的存储空间。但是在存储代价已经很低廉的情况下,优先考虑兼容性会给你带来更多好处的,效率没有varchar高。
(4)为什么要用nvarchar?
有n前缀的,n表示Unicode字符,即所有字符都占两个字节,nchar,nvarchar
字符中,英文字符只需要一个字节存储就足够了,但汉字众多,需要两个字节存储,英文与汉字同时存在时容易造成混乱,Unicode 字符集就是为了解决字符集这种不兼容的问题而产生的,它所有的字符都用两个字节表示,即英文字符也是用两个字节表示。
(5)有关var的简单介绍:
有var前缀的,表示是实际存储空间是变长的, varchar,nvarchar
所谓定长就是长度固定的,当输入的数据长度没有达到指定的长度时将自动以英文空格在其后面填充,使长度达到相应的长度;而变长字符数据则不会以空格填充,比较例外的是,text 存储的也是可变长。
(6)如何使用这些类型?
如果你肯定存储的数据长度,而且不包中文的,可以选择char类型。
如果肯定存储的数据长度,但可能包括中文,可以选择nchar类型。
如果不确定存储的数据长度,存储只有英文、数字的最好用varchar。
如果不确定存储的数据长度,也有可能有中文,可以选择nvarchar类型。
2、变量赋值
测试数据表
测试数据
变量TestId赋值
DECLARE @TestId NVARCHAR(20)='aaaaa'
DECLARE @SumQty FLOAT=10
DECLARE @CountQty FLOAT=10
SELECT * FROM Test
SELECT @TestId=TestId FROM Test WHERE TestId ='K'
SELECT @SumQty=SUM(Qty),@CountQty=COUNT(Qty) FROM Test WHERE TestId ='K'
SELECT @TestId AS TestId,@SumQty AS SumQty,@CountQty AS CountQty
运行结果
查看以上语句执行结果差异,同时也需要特别注意变量@Testld未能成功赋值(即由于查询记录不存在,导致@Testld 变量还是默认初始值aaaaa),在实施中经常会出现莫名奇妙问题,很多时候就是这原因导致的,特别是在写循环语句内,通过SELECT查询对变量赋值,一定需要先赋默认值(根据变量类型分别建议设置=’ ‘或=0)。
3、SELECT查询
先看几个例子,大家看下查询结果是否与想想的是一致的,如下为对应创建表结构语句及表初始数据。
CREATE TABLE [dbo]. [A](
[AId] [nvarchar] (50) NULL,
[CName] [nvarchar] (50) NULL
)
CREATE TABLE [dbo]. [B](
[BId] [nvarchar] (50) NULL,
[AId] [nvarchar] (50) NULL,
[CValues] [nvarchar] (50) NULL
)
INSERT INTO A ( AId, CName ) VALUES ('1','王XX')
INSERT INTO A ( AId, CName ) VALUES ('2','陈XX')
INSERT INTO A ( AId, CName ) VALUES ('3','李XX' )
INSERT INTO B ( BId, AId, CValues ) VALUES ('B00001','1','B1')
INSERT INTO B ( BId,AId, CValues ) VALUES ( 'B00002','1','B2')
INSERT INTO B ( BId,AId, CValues ) VALUES ( 'B00003','2','B3')
(1)内连接与左连接的差异
SELECT A.*,B.* FROM A INNER JOIN B ON A.AId=B.AId [SELECT A.*,B.* FROM A,B WHERE A.AId=B.AId]
SELECT A.*,B.* FROM A LEFT JOIN B ON A.AId=B.AId
(2)左连接带查询条件1–ON涉及增加连接右边表的条件
SELECT A.*,B.* FROM A LEFT JOIN B ON A.AId=B.AId
SELECT A.*,B.* FROM A LEFT JOIN B ON A.AId=B.AId AND B.CValues='B3'
-- 返回数据行数不同,是由于B.CValues='B3'条件过滤表B只有1条记录,再与A表连接,类似下面逻辑查询
SELECT A.*,B.* FROM A LEFT JOIN(SELECT * FROM B WHERE B.CValues='B3') B ON A.AId=B.AId
左表A数据都有,右表B数据只有满足B.Cvalues是B3的才有数据,其他为null。相当于只关联符合B.Cvalues=’ B3’的B,其他为null,得到的结果。
(3)左连接带查询条件1–ON涉及连接左边表的条件
SELECT A.*,B.* FROM A LEFT JOIN B ON A.AId=B.AId AND A.CName=''
SELECT A.*,B.* FROM A LEFT JOIN B ON A.AId=B.AId AND A.CName='王XX'
SELECT A.*,B.* FROM A LEFT JOIN B ON A.AId=B.AId AND A.CName='陈XX'
始终记住LEFT JOIN,左表A数据都有,如果加入左表A条件CName=’王XX’,则只有满足A. CName=’王XX’,对应的右表B. Ald 为A.CName=’王XX’对应Ald的才有数据,其他为null。相当于只关联符合A.CName=’王XX’的Ald,其他为null,得到的结果。
原创文章,作者:dweifng,如若转载,请注明出处:https://blog.ytso.com/274656.html