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

When is nvarchar(Max) = nvarchar(4000)?

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

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

我已经收集了一些 suggestions/partial 个答案:

  1. 是否有仅支持最多 4000 个的旧 SQL 服务器版本?
  2. 在将 nvarchar(max) variable/column 分配给非最大尺寸组件的串联时,我们必须将所有内容显式转换为 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. 是的。 (n)varchar(MAX)introduced in SQL Server 2005。以前,您必须为 varchar(MAX)nvarchar(MAX)varbinary(MAX) 使用 textntextimage。旧数据类型已被弃用很长时间,您不应该使用它们。
  2. 合并数据时,data type precedence is used to work out the final data type. When lengths are involved, the combined values of the lengths are used (A varchar(10) and a varchar(100) concatenated would return a varchar(110). Note, however, that to achieve the usage of the MAX length, at least one string must be an (n)varchar(MAX). SELECT REPLICATE(N'A',3000) + REPLICATE(N'A',3000) AS S would return a 4000 character string. + (String Concatenation) (Transact-SQL) - Remarks

    If the result of the concatenation of strings exceeds the limit of 8,000 bytes, the result is truncated. However, if at least one of the strings concatenated is a large value type, truncation does not occur.

  3. 禁用什么功能? (n)varchar(MAX)的用法?为什么?如果您想阻止人们使用某种数据类型,请阻止他们使用 (n)textimage。不过,严肃地说,您无法停止使用数据类型。也许您可以使用 DDL 触发器获得 "clever",但我建议不要这样做。

    要回答编辑,sp_tableoption 不能用来阻止某人使用 MAX 长度数据类型 no;我的上述观点是成立的。引用文档(sp_tableoption (Transact-SQL) - Arguments

    Large value types out of row:
    1 = varchar(max), nvarchar(max), varbinary(max), xml and large user-defined type (UDT) columns in the table are stored out of row, with a 16-byte pointer to the root.

    0 = varchar(max), nvarchar(max), varbinary(max), xml and large UDT values are stored directly in the data row, up to a limit of 8000 bytes and as long as the value can fit in the record. If the value does not fit in the record, a pointer is stored in-row and the rest is stored out of row in the LOB storage space. 0 is the default value.

    Large user-defined type (UDT) applies to: SQL Server 2008 through SQL Server 2017.

    Use the TEXTIMAGE_ON option of CREATE TABLE to specify a location for storage of large data types.

  4. SO 太宽泛了。