NVARCHAR(MAX) 的最大长度

在SQL Server 2017环境下,NVARCHAR(MAX)类型允许的最大存储空间为2GB。无论是在数据表中作为列定义还是作为变量使用,这一限制都适用。然而,某些字符串函数如replicate()返回的字符串长度受限于8000B,但将多个NVARCHAR(MAX)变量拼接时,总存储可达2GB。此特性在执行动态SQL时尤其重要,如构建大规模TSQL脚本时。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文使用的环境是SQL Server 2017, 主机是64位操作系统。

大家都知道,Micorosoft Docs对 max参数的定义是:max 指定最大的存储空间是2GB,这个结论是正确的。

nvarchar [ ( n | max ) ]
Variable-size string data. n defines the string size in byte-pairs and can be a value from 1 through 4,000. max indicates that the maximum storage size is 2^30-1 characters (2 GB).

结论1:

当定义数据表的一个nvarchar(max)类型的数据列时,该类型存储数据的最大空间是2GB。

当定义nvarchar(max)类型的变量时,该变量的最大空间是2GB。

结论2:

当定义一个nvarchar(max)类型的变量时,该变量的最大存储空间是2GB。但是有些字符串函数处理的结果可能不会多于8000B,做一个简单的测试,调用replicate()函数,对一个Unicode 字符(占2B)重复5000次,返回的字符串的最大长度是8000B,即使多次拼接也不能突破8000B的限制:

print datalength(replicate(N'a',5000))
print datalength(replicate(N'a',5000)+replicate(N'a',5000))

即使把replicate()函数返回的结果赋值给nvarchar(max)类型的变量,也不突破8000B的限制。

declare @txt nvarchar(max)
set @txt= replicate(N'a',5000)
print datalength(@txt)

结论3:

当定义一个nvarchar(max)类型的变量时,把多个nvarchar(max)类型的变量进行拼接,最大的存储空间是2GB。

例如,下面的示例,输出的结果是16000,这代表@cmd变量存储的空间是16000B:

declare @cmd varchar(max)
set @cmd = 'print /*' + replicate ('-', 7990);
set @cmd = @cmd + replicate ('-', 7990) + '*/ getdate()';
exec (@cmd)
print datalength (@cmd)

对结论3的应用:执行动态SQL,传递的TSQL脚本的最大字符数量是2GB

举个例子,从数据库中查询所有数据表的结构,并获取每一列的一个样本值,可以考虑使用动态SQL

declare @sql nvarchar(max)

;with cte_table  as
(
    select s.name as table_schema
        ,o.name as table_name
        ,c.name as column_name
        ,t.name as data_type
    from sys.tables o
    inner join sys.schemas s
        on o.schema_id=s.schema_id
    inner join sys.columns c
        on o.object_id=c.object_id
    inner join sys.types t
        on c.user_type_id=t.user_type_id
)
select @sql=coalesce(@sql+N'union ',N'')
        +formatmessage(N'select top 1 table_name=''%s'',column_name=''%s'',data_type=''%s'',sample=cast(%s as nvarchar(max)) from %s'
        +nchar(10),table_name, column_name, data_type, column_name, table_schema + '.' + table_name)
from cte_table
where table_schema='xxx' 

print datalength(@sql)
print @sql

 

 

参考文档:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悦光阴

你的鼓励是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值