我知道NVARCHAR(MAX)
设置了4000的最大值。
你的理解是错误的。nvarchar(max)
可以存储多达2GB的数据(有时甚至更多,相当于10亿双字节字符)。
根据书籍在线中的nchar和nvarchar语法规则。
nvarchar [ ( n | max ) ]
|
字符表示这些是备选项,即您可以指定
n
或文字
max
。
如果选择指定特定的
n
,则此值必须介于1和4000之间,但使用
max
定义它为大型对象数据类型(代替已弃用的
ntext
)。
实际上,在SQL Server 2008中,对于
变量而言,可以无限制地超越2GB限制,前提是
tempdb
有足够的空间。(
显示在此处)
关于您问题的其他部分:
连接时的截断取决于数据类型。
varchar(n) + varchar(n)
将在8000个字符处截断。
nvarchar(n) + nvarchar(n)
将在4000个字符处截断。
varchar(n) + nvarchar(n)
将在4000个字符处截断。由于nvarchar
的优先级更高,因此结果为nvarchar(4000)
[n]varchar(max)
+[n]varchar(max)
不会截断(对于<2GB)。
varchar(max)
+varchar(n)
不会截断(对于<2GB),结果将被定义为varchar(max)
。
varchar(max)
+nvarchar(n)
不会截断(对于<2GB),结果将被定义为nvarchar(max)
。
nvarchar(max)
+varchar(n)
将首先将varchar(n)
输入转换为nvarchar(n)
,然后进行连接。如果varchar(n)
字符串的长度大于4000个字符,则将强制转换为nvarchar(4000)
并进行截断 。
字符串字面值的数据类型
如果使用N
前缀,并且字符串< = 4000个字符长,则它将被视为nvarchar(n)
,其中n
是字符串的长度。例如,N'Foo'
将被视为nvarchar(3)
。如果字符串长度超过4000个字符,则将其视为nvarchar(max)
如果未使用N
前缀,并且字符串<= 8000个字符长,则它将被视为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
位避免了像<
这样的字符显示为<
时出现的问题。