SO和其他网站上都有多个帖子,其中明确指出nvarchar(max)
的最大长度为2GB。但是,在Internet和现实生活中,我也感到很多困惑,因为它实际上是Unicode的8000/4000。
我想知道什么事情可以改变这个事实,或者可能导致某人错误地假设这一事实。
我已经收集了一些建议/部分答案:
在将nvarchar(max)
变量/列分配给非最大大小的组件的串联时,我们是否必须将所有内容都明确转换为nvarchar(max)
?这是一个奇怪的例子,其中返回文本的函数需要转换,而文字的N可以省略:
declare @s nvarchar(max)
select @s = convert(nvarchar(max), replicate('.', 8000)) + N'Hi!'
select len(@s) -- returns 8003
declare @s nvarchar(max)
select @s = replicate('.', 8000) + N'Hi!'
select len(@s) -- returns 4000
declare @s nvarchar(max)
select @s = convert(nvarchar(max), replicate('.', 8000)) + 'Hi!'
select len(@s) -- returns 8003
是否有禁用功能的方法? sp_tableoption @OptionName=large value types out of row
或OBJECTPROPERTY(id,'TableTextInRowLimit')
与此有关吗?
说明:我的目的不是使用此功能,而是要知道它的存在,它可能确实是由较高特权的用户使用的,它会阻止 me 使用最大尺寸。
很高兴欢迎其他任何观点
答案 0 :(得分:3)
这里有几点,我无法发表评论。
(n)varchar(MAX)
是introduced in SQL Server 2005。以前,您必须为text
,ntext
和image
使用varchar(MAX)
,nvarchar(MAX)
和varbinary(MAX)
。旧数据类型已被弃用很长时间了,您不应该使用它们。varchar(10)
和varchar(100)
将返回varchar(110)
。但是请注意,要实现{{ 1}}的长度,至少一个字符串必须为MAX
。(n)varchar(MAX)
将返回4000个字符串。+ (String Concatenation) (Transact-SQL) - Remarks:
如果字符串连接的结果超过了8,000个字节的限制,则结果将被截断。但是,如果串联的字符串中至少有一个是大值类型,则不会发生截断。
SELECT REPLICATE(N'A',3000) + REPLICATE(N'A',3000) AS S
的用法?为什么?如果要停止使用数据类型的人,请使用(n)varchar(MAX)
和(n)text
停止他们。严格地说,您不能停止使用数据类型。也许您可以使用DDL触发器“巧妙地”使用,但我建议不要这样做。 image
不能用来阻止使用sp_tableoption
长度数据类型no的某人;我的上述观点立场。引用文档(sp_tableoption (Transact-SQL) - Arguments:
行外的大值类型:
1 =MAX
,varchar(max)
,nvarchar(max)
,varbinary(max)
和表中的大型用户定义类型(UDT)列存储在行外,并带有16字节指针扎根。
0 =xml
,varchar(max)
,nvarchar(max)
,varbinary(max)
,并且较大的UDT值直接存储在数据行中,最多8000个字节,并且与该值一样长可以适合记录。如果该值不适合记录,则将指针存储在行中,其余的存储在LOB存储空间的行外。默认值为0。
大型用户定义类型(UDT)适用于:SQL Server 2008到SQL Server2017。
使用xml
的{{1}}选项来指定用于存储大型数据类型的位置。