【问题标题】:When is nvarchar(Max) = nvarchar(4000)?什么时候 nvarchar(Max) = nvarchar(4000)?
【发布时间】:2019-03-29 10:16:31
【问题描述】:

在 SO 和其他网站上有多个帖子明确指出 nvarchar(max) 的最大长度为 2GB。但是,我在互联网和现实生活中也看到很多混淆,它实际上是 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. 欢迎任何其他观点

【问题讨论】:

  • 而且从来没有出现过nvarchar(max) 为 4000 的情况。以前的情况是 max 关键字在此上下文中不存在,而您的最大数量可以指定为 4000 但这并不完全相同。此外,如果您受到此影响,您将遇到更大的问题,因为没有max 支持的上一个版本是SQL Server 2000,它long 不再支持。
  • 还有很多关于字符串连接的问题,最终会回到this documentation:“如果字符串连接的结果超过了8000字节的限制,结果会被截断。但是,如果连接的字符串中至少有一个是大值类型,不会发生截断。"
  • @Damien_The_Unbeliever 1. 哇,甚至超过 2GB?有趣的。不过我对 2GB 没问题,所以我不会在 atm 上搜索太多。 2. v2000 是第一个支持(或最后一个不支持?)nax 支持的花絮对我来说很重要,也许是一个答案?因为我在 MS 文档上找不到该链接,所以我永远无法确定。
  • @GeorgeMenoutis 您应该阅读文档,而不是可能提及您的问题的零散答案。没有混乱。文档对所有这些都非常清楚。 BLOB/CLOB 类型中从来没有任何 4K 字符限制。 text/ntext/image 基本上永远被弃用了。很少提及古代类型,因为它们永远不应该被使用。这些参考资料表明它们不应该被使用。

标签: sql-server tsql nvarchar


【解决方案1】:

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

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

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

  3. 禁用什么功能? (n)varchar(MAX)的用法?为什么?如果您想阻止人们使用数据类型,请使用 (n)textimage 阻止他们。不过说真的,您不能停止使用数据类型。也许您可以使用 DDL 触发器变得“聪明”,但我建议您不要这样做。

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

    行外的大值类型:
    1 = varchar(max)nvarchar(max)varbinary(max)xml 和表中的大型用户定义类型 (UDT) 列存储在行外,并带有指向根的 16 字节指针。
    0 = varchar(max)nvarchar(max)varbinary(max)xml 和大的 UDT 值直接存储在数据行中,最大限制为 8000 字节,只要值可以适合记录。如果该值不适合记录,则将指针存储在行内,其余的将存储在 LOB 存储空间中的行外。 0 是默认值。

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

    使用CREATE TABLETEXTIMAGE_ON 选项指定存储大型数据类型的位置。

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

【讨论】:

  • 由于 OP 的评论表明他们无法在 MS 文档中找到 1 的答案,因此我冒昧地添加了指向您答案的链接。
  • 谢谢@Damien_The_Unbeliever。我看到你也找到了+ 文档,希望你不介意我窃取了那个引用。
  • 我已经添加了关于 3 的说明。
  • 为您@GeorgeMenoutis 添加了更多关于 3 的说明,但没有改变答案。
猜你喜欢
  • 1970-01-01
  • 2021-06-26
  • 1970-01-01
  • 1970-01-01
  • 2013-12-12
  • 2016-09-24
  • 1970-01-01
  • 2011-01-09
  • 1970-01-01
相关资源
最近更新 更多