什么时候nvarchar(Max)= nvarchar(4000)?

时间:2019-03-29 10:16:32

标签: sql-server tsql nvarchar

SO和其他网站上都有多个帖子,其中明确指出nvarchar(max)的最大长度为2GB。但是,在Internet和现实生活中,我也感到很多困惑,因为它实际上是Unicode的8000/4000。

我想知道什么事情可以改变这个事实,或者可能导致某人错误地假设这一事实。

我已经收集了一些建议/部分答案:

  1. 是否存在仅最多支持4000个的较旧的SQL Server版本?
  2. 在将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
    
  3. 是否有禁用功能的方法? sp_tableoption @OptionName=large value types out of rowOBJECTPROPERTY(id,'TableTextInRowLimit')与此有关吗?

    说明:我的目的不是使用此功能,而是要知道它的存在,它可能确实是由较高特权的用户使用的,它会阻止 me 使用最大尺寸。

  4. 很高兴欢迎其他任何观点

1 个答案:

答案 0 :(得分:3)

这里有几点,我无法发表评论。

  1. 是的。 (n)varchar(MAX)introduced in SQL Server 2005。以前,您必须为textntextimage使用varchar(MAX)nvarchar(MAX)varbinary(MAX)。旧数据类型已被弃用很长时间了,您不应该使用它们。
  2. 合并数据时,data type precedence用于得出最终数据类型。当涉及长度时,将使用长度的组合值(串联的A varchar(10)varchar(100)将返回varchar(110)。但是请注意,要实现{{ 1}}的长度,至少一个字符串必须为MAX(n)varchar(MAX)将返回4000个字符串。+ (String Concatenation) (Transact-SQL) - Remarks
      

    如果字符串连接的结果超过了8,000个字节的限制,则结果将被截断。但是,如果串联的字符串中至少有一个是大值类型,则不会发生截断。

  3. 禁用什么功能? 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 = MAXvarchar(max)nvarchar(max)varbinary(max)和表中的大型用户定义类型(UDT)列存储在行外,并带有16字节指针扎根。

      0 = xmlvarchar(max)nvarchar(max)varbinary(max),并且较大的UDT值直接存储在数据行中,最多8000个字节,并且与该值一样长可以适合记录。如果该值不适合记录,则将指针存储在行中,其余的存储在LOB存储空间的行外。默认值为0。

      大型用户定义类型(UDT)适用于:SQL Server 2008到SQL Server2017。

      使用xml的{​​{1}}选项来指定用于存储大型数据类型的位置。

  4. 对于SO来说太宽泛了。