关于 varchar max的误区

46 2019-3-15 08:14

我们知道varchar(max)是微软用来替代text数据类型的,后续的版本text 等老的字段类型可能会被取消。

所以text能存的,varchar(max)肯定能存下。 其实它能够存放的字符数是非常大的。


varchar(max)可以存放2^31-1个字节


可以存储的4.2亿 个字符 我相信很难达到的.所以当遇到 貌似“存不下”的情况,尽量多检查下其他的原因


下面针对可能遇到的情况给出解决方案


字符串被截断

declare @test varchar(max)
set @test=replicate('1',9000)
print len(@test)


解决办法1:

使用强制转换

set @test=replicate(convert(varchar(max),'1'),9000)--强制转换为varchar(max)。
print len(@test)


解决办法2

把9000个字符拆分成2个部分,每个部分都少于8000

set @test=replicate(convert(varchar(max),'1'),4000)+replicate(convert(varchar(max),'1'),5000)
print len(@test)


这里有一个坑,就是print @test

你把这个文本内容copy出来后发现字符只有8000个

这是因为, print是无法线上超过8000的长度,我们查看尽量用len 去查看

查看内容时数据少了

有时候只看len我们 心里肯定不踏实,还是想看看内容是否全部保存了

set @test=replicate(convert(varchar(max),'1'),99000)
select @test

对应select 的结果发现长度为43680

这是因为在SSMS 选项中,以网格显示结果对应非xml最多可以65535个字符。

那么我们就有另外的一个办法了

SELECT CAST('<A><![CDATA[' + CAST(@test as nvarchar(max)) + ']]></A>' as xml)

把上面的语句转换为xml文件,就可以显示99001了

或者

把select出来的结果 另存为CSV 也可以看到完整的记录

盲目的把数据复制了出来,发现数据是截断的,结果以为是这个导致了问题,如果数据超过了8000个字符,右键复制数据,复制出来的其实是不完整的数据,其实数据存入数据库的数据是完整的


    可以通过PRING(len(字段))来查看长度或者LEFT和RIGHT来看末尾和前端数值

SELECT     [列名] AS 正常,
        RIGHT([列名],3) AS 右边3位,
        LEFT([列名],3) AS 左边3位
        FROM 表名


    导致这个原因就是复制数据的时候是有长度限制的,最高就是8000个字符