【问题标题】:SQL Server 2008 Nvarchar(Max) concatenation - Truncation issueSQL Server 2008 Nvarchar(Max) 连接 - 截断问题
【发布时间】:2015-07-08 00:41:48
【问题描述】:

谁能解释一下为什么在 SQL Server 2008 上会发生这种情况:

declare @sql Nvarchar(max);

set @sql =N'';

select @sql = @sql +replicate('a',4000) + replicate('b', 6000);

select len(@sql)

回报:8000

多个网站建议,只要第一个变量的类型为 NVARCHAR(MAX),就不应该发生截断,但它仍然会发生。

【问题讨论】:

  • 从谷歌搜索你会得到“Varchar(Max) 字段在 8000 个字符 SQL Server 2008 后截断数据。我有一个字段来存储一些数据,该字段被声明为 varchar(Max) 。据我了解,这应该存储 2^31 - 1 个字符,但是当我输入一些超过 8000 个字符的内容时,它会切断其余部分”
  • 这可能会有所帮助:dba.stackexchange.com/questions/18483/…

标签: sql-server tsql sqldatatypes nvarchar truncation


【解决方案1】:

因为'a''b' 不是NVARCHAR(MAX) 类型

像这样,它应该可以工作:

declare @sql Nvarchar(max),
   @a nvarchar(max),
   @b nvarchar(max);

select @sql =N'', @a = N'a', @b = N'b';

select @sql = @sql +replicate(@a,4000) + replicate(@b, 6000);

select len(@sql)

这是微软 REPLICATE 函数信息的链接: https://msdn.microsoft.com/en-us/library/ms174383.aspx

里面写着:

如果 string_expression 不是 varchar(max) 或 nvarchar(max) 类型,则 REPLICATE 将返回值截断为 8,000 字节。要返回大于 8,000 字节的值,必须将 string_expression 显式转换为适当的大值数据类型。

【讨论】:

  • 在我的示例中,两个 REPLICATE 返回的字符串已经小于 8000 字节,因此在复制本身内部不应该出现截断问题。这是否意味着如果我在 T-SQL 中连接 100 多个字符串以构造最终的动态 SQL NVARCHAR(MAX) 字符串,则必须将所有 100 多个字符串强制转换为 NVARCHAR(MAX) 以避免 8000 多个截断问题?
  • @TomatoGuy,没有N,它们是常规类型varchar,最大长度为8000。没有将变量定义为nvarchar(max),而是N,它们将是常规的nvarchar,最大长度为 4000。大多数 TSQL 函数在返回结果时会为您提供最小的输入类型。我会看看我是否可以拉出包含该信息的链接。
  • REPLICATE 会返回一个VARCHAR(8000) 所以当你+ 他们在一起时,结果不会超过VARCHAR(8000)
  • Conversion from large-value data types, such as varchar(max), to a smaller counterpart data type, such as varchar, is an implicit conversion, but truncation will occur if the large value is too big for the specified length of the smaller data type. msdn.microsoft.com/en-us/library/ms187928.aspx
【解决方案2】:

至于为什么,我不知道。我只知道 NVARCHAR 喜欢在 8000 处切断,除非您将内容转换为 NVARCHAR(MAX) 或者您可以使用 CONCAT():

DECLARE @sql Nvarchar(max);

SELECT @sql = CONCAT(@sql,replicate('a',4000),replicate('b', 6000)) --do it this way

--SELECT @sql = CAST(replicate('a',4000) AS NVARCHAR(MAX)) + CAST(replicate('b', 6000) AS NVARCHAR(MAX)) --or this way

两者都导致 LEN(@sql) 为 10,000

【讨论】:

  • -1 因为 nvarchar 被限制为 4000 没有 max 的大小。 varchar 在没有 max 的情况下限制为 8000 个。为concat 方法+1,但转换复制的字符串也有效:replicate( cast('a' as nvarchar(max)), 4000) + replicate( cast('b' as nvarchar(max)), 6000)。 OP 可以选择在给定时间最有效的路线。
  • 谢谢。这就是我列出这两个选项的原因。
猜你喜欢
  • 1970-01-01
  • 2022-11-26
  • 1970-01-01
  • 1970-01-01
  • 2011-06-17
  • 2010-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多