Entiendo que hay un máximo de 4000 establecido para NVARCHAR(MAX)
Tu comprensión está mal. nvarchar(max)
puede almacenar hasta (y a veces más) 2 GB de datos (mil millones de caracteres de doble byte).
De nchar y nvarchar en Libros en línea, la gramática es
nvarchar [ ( n | max ) ]
El |
personaje significa que estas son alternativas. es decir, se especifica ya sea n
o lo literal max
.
Si elige especificar un tipo específico n
, debe estar entre 1 y 4.000, pero el uso lo max
define como un tipo de datos de objeto grande (el reemplazo ntext
está obsoleto).
De hecho, en SQL Server 2008 parece que para una variable, el límite de 2 GB se puede exceder indefinidamente sujeto a suficiente espacio en tempdb
(se muestra aquí )
Respecto a las otras partes de su pregunta
El truncamiento al concatenar depende del tipo de datos.
varchar(n) + varchar(n)
se truncará a los 8.000 caracteres.
nvarchar(n) + nvarchar(n)
se truncará a 4.000 caracteres.
varchar(n) + nvarchar(n)
se truncará a 4.000 caracteres. nvarchar
tiene mayor precedencia por lo que el resultado esnvarchar(4,000)
[n]varchar(max)
+ [n]varchar(max)
no se truncará (para <2GB).
varchar(max)
+ varchar(n)
no se truncará (para <2GB) y el resultado se escribirá como varchar(max)
.
varchar(max)
+ nvarchar(n)
no se truncará (para <2GB) y el resultado se escribirá como nvarchar(max)
.
nvarchar(max)
+ varchar(n)
primero convertirá la varchar(n)
entrada nvarchar(n)
ay luego hará la concatenación. Si la longitud de la varchar(n)
cadena es superior a 4.000 caracteres, la nvarchar(4000)
conversión será ay se producirá el truncamiento .
Tipos de datos de cadenas literales
Si usa el N
prefijo y la cadena tiene <= 4.000 caracteres de longitud, se escribirá nvarchar(n)
donde n
es la longitud de la cadena. Así N'Foo'
será tratado como nvarchar(3)
por ejemplo. Si la cadena tiene más de 4000 caracteres, se tratará comonvarchar(max)
Si no usa el N
prefijo y la cadena tiene <= 8,000 caracteres de longitud, se escribirá varchar(n)
donde n
es la longitud de la cadena. Si más largo comovarchar(max)
Para ambos de los anteriores, si la longitud de la cadena es cero, n
se establece en 1.
Elementos de sintaxis más nuevos.
1. La CONCAT
función no ayuda aquí
DECLARE @A5000 VARCHAR(5000) = REPLICATE('A',5000);
SELECT DATALENGTH(@A5000 + @A5000),
DATALENGTH(CONCAT(@A5000,@A5000));
Lo anterior devuelve 8000 para ambos métodos de concatenación.
2. Tenga cuidado con+=
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);`
Devoluciones
-------------------- --------------------
8000 10000
Tenga en cuenta que @A
encontró truncamiento.
Cómo resolver el problema que está experimentando.
Obtiene truncamiento porque está concatenando dos max
tipos que no son de datos juntos o porque está concatenando una varchar(4001 - 8000)
cadena a una nvarchar
cadena escrita (par nvarchar(max)
).
Para evitar el segundo problema, simplemente asegúrese de que todos los literales de cadena (o al menos aquellos con longitudes en el rango 4001 - 8000) estén precedidos por N
.
Para evitar el primer problema, cambie la asignación de
DECLARE @SQL NVARCHAR(MAX);
SET @SQL = 'Foo' + 'Bar' + ...;
A
DECLARE @SQL NVARCHAR(MAX) = '';
SET @SQL = @SQL + N'Foo' + N'Bar'
de modo que an NVARCHAR(MAX)
esté involucrado en la concatenación desde el principio (como resultado de cada concatenación también será, NVARCHAR(MAX)
esto se propagará)
Evitar el truncamiento durante la visualización
Asegúrese de tener seleccionado el modo "resultados a la cuadrícula", luego puede usar
select @SQL as [processing-instruction(x)] FOR XML PATH
Las opciones de SSMS le permiten establecer una duración ilimitada para los XML
resultados. El processing-instruction
bit evita problemas con personajes como <
aparecer como <
.