我了解NVARCHAR(MAX) 的最大设置为 4000
你的理解是错误的。 nvarchar(max) 最多可以存储(有时甚至超过)2GB 的数据(10 亿个双字节字符)。
来自在线书籍中的nchar and nvarchar,语法是
nvarchar [ ( n | max ) ]
| 字符表示这些是替代品。即您指定 either n 或文字 max。
如果您选择指定特定的n,则该值必须介于 1 和 4,000 之间,但使用 max 会将其定义为大对象数据类型(替换 ntext,已弃用)。
事实上,在 SQL Server 2008 中,对于一个变量,如果tempdb (Shown here) 中有足够的空间,似乎可以无限期超过 2GB 的限制
关于你问题的其他部分
连接时的截断取决于数据类型。
-
varchar(n) + varchar(n) 将截断 8,000 个字符。
-
nvarchar(n) + nvarchar(n) 将截断 4,000 个字符。
-
varchar(n) + nvarchar(n) 将截断 4,000 个字符。 nvarchar 具有更高的优先级,因此结果为 nvarchar(4,000)
-
[n]varchar(max) + [n]varchar(max) 不会截断(对于
-
varchar(max) + varchar(n) 不会截断(对于 varchar(max)。
-
varchar(max) + nvarchar(n) 不会截断(对于 nvarchar(max)。
-
nvarchar(max) + varchar(n) 将首先将varchar(n) 输入转换为nvarchar(n),然后进行连接。 如果 varchar(n) 字符串的长度大于 4,000 个字符,则强制转换为 nvarchar(4000) 并且会发生截断。
字符串字面量的数据类型
如果您使用N 前缀并且字符串长度nvarchar(n),其中n 是字符串的长度。所以 N'Foo' 将被视为 nvarchar(3) 例如。如果字符串长度超过 4,000 个字符,它将被视为nvarchar(max)
如果您不使用N 前缀并且字符串长度varchar(n),其中n 是字符串的长度。如果长为varchar(max)
对于上述两种情况,如果字符串的长度为零,则 n 设置为 1。
较新的语法元素。
1.CONCAT 函数在这里没有帮助
DECLARE @A5000 VARCHAR(5000) = REPLICATE('A',5000);
SELECT DATALENGTH(@A5000 + @A5000),
DATALENGTH(CONCAT(@A5000,@A5000));
以上两种连接方法都返回 8000。
2.小心+=
DECLARE @A VARCHAR(MAX) = '';
SET @A+= REPLICATE('A',5000) + REPLICATE('A',5000)
DECLARE @B VARCHAR(MAX) = '';
SET @B = @B + REPLICATE('A',5000) + REPLICATE('A',5000)
SELECT DATALENGTH(@A),
DATALENGTH(@B);`
返回
-------------------- --------------------
8000 10000
注意@A 遇到了截断。
如何解决您遇到的问题。
由于您将两个非 max 数据类型连接在一起,或者因为您将 varchar(4001 - 8000) 字符串连接到 nvarchar 类型的字符串(甚至是 nvarchar(max)),您将被截断。
要避免第二个问题,只需确保所有字符串文字(或至少那些长度在 4001 - 8000 范围内的字符串)都以 N 开头。
为了避免第一个问题,将分配从
DECLARE @SQL NVARCHAR(MAX);
SET @SQL = 'Foo' + 'Bar' + ...;
到
DECLARE @SQL NVARCHAR(MAX) = '';
SET @SQL = @SQL + N'Foo' + N'Bar'
因此NVARCHAR(MAX) 从一开始就参与串联(因为每个串联的结果也将是NVARCHAR(MAX) 这将传播)
查看时避免截断
确保您选择了“结果到网格”模式,然后您可以使用
select @SQL as [processing-instruction(x)] FOR XML PATH
SSMS 选项允许您为XML 结果设置无限长度。 processing-instruction 位避免了诸如< 等字符显示为< 的问题。