nvarchar(MAX)变量存储JSON数据被截断,求问题原因
问题描述
现有如下代码:
DECLARE @DocJSONGoods nvarchar(MAX) SELECT @DocJSONGoods = ( SELECT ProductsItems, DocCDProductsChapterNumber, DocCDProductsNomenclatureData, DocCDProductsPurchase, DocCDProductsAmount, DocCDProductsValue, DocCDProductsCountry FROM @TabChaptersGoods FOR JSON PATH, ROOT('DocCDProductsList') )
该代码从表变量@TabChaptersGoods中提取92条记录(其中DocCDProductsNomenclatureData、DocCDProductsPurchase字段为nvarchar(MAX)类型且存储JSON数据),通过FOR JSON PATH生成JSON并赋值给nvarchar(MAX)类型变量@DocJSONGoods,操作本身并无特殊之处。
但最终得到的JSON仅包含29条完整记录,第30条记录被截断,且截断位置恰好处于其中一个nvarchar(max)字段的JSON内容中。
执行SELECT LEN(@DocJSONGoods)得到的长度为213565,而从SSMS结果网格复制@DocJSONGoods内容到Notepad++后,长度仅为72133,内容包含拉丁语和西里尔语Unicode字符。
尝试改用循环拼接记录到@DocJSONGoods的方式,最终结果仍类似:第30条记录被截断(截断位置略有不同)。
问题与成因分析
核心问题
这是SSMS结果显示和复制的截断限制问题,SQL Server实际已经完整生成并存储了JSON内容,只是SSMS没有完整展示或允许复制全部内容。
成因
- SSMS的默认输出限制:SSMS对结果网格中单个单元格的内容有默认长度限制,默认情况下
nvarchar(MAX)类型的内容仅会显示前65536字节(对应32768个左右的Unicode字符)。当内容超过这个阈值,SSMS会截断显示,复制操作也只能获取到截断后的内容。你通过LEN(@DocJSONGoods)得到的213565是变量中实际存储的字符数,证明SQL Server端的JSON生成和存储是完整的。 - Unicode字符的加速截断:因为内容包含拉丁语、西里尔语等Unicode字符,每个字符占用2字节,SSMS的字节限制会更快触发截断,导致复制到Notepad++后的字符数看起来更少。
- 循环拼接的假象:改用循环拼接后仍出现截断,本质还是SSMS的输出限制导致的,并非拼接过程本身截断了内容。
内容的提问来源于stack exchange,提问作者geenSf
相关产品推荐
相关产品推荐

