Entendo que há um conjunto máximo de 4000 paraNVARCHAR(MAX)
Seu entendimento está errado.
nvarchar(max)
pode armazenar até (e às vezes além) 2 GB de dados (1 bilhão de caracteres de byte duplo). De nchar e nvarchar em Livros online a gramática é
nvarchar [ ( n | max ) ]
O
|
caractere significa que estas são alternativas. ou seja, você especifica ou n
ou o literal max
. Se você optar por especificar um
n
específico então isso deve estar entre 1 e 4.000, mas usando max
define-o como um tipo de dados de objeto grande (substituto para ntext
que está obsoleto). De fato, no SQL Server 2008, parece que para uma variável o limite de 2 GB pode ser excedido indefinidamente sujeito a espaço suficiente em
tempdb
(Mostrado aqui) Em relação às outras partes da sua pergunta
O truncamento ao concatenar depende do tipo de dados.
varchar(n) + varchar(n)
será truncado em 8.000 caracteres.nvarchar(n) + nvarchar(n)
será truncado em 4.000 caracteres.varchar(n) + nvarchar(n)
truncará em 4.000 caracteres.nvarchar
tem maior precedência, então o resultado énvarchar(4,000)
[n]varchar(max)
+[n]varchar(max)
não será truncado (para <2 GB).varchar(max)
+varchar(n)
não truncará (para <2 GB) e o resultado será digitado comovarchar(max)
.varchar(max)
+nvarchar(n)
não truncará (para <2 GB) e o resultado será digitado comonvarchar(max)
.nvarchar(max)
+varchar(n)
primeiro converterá ovarchar(n)
entrada paranvarchar(n)
e depois faça a concatenação. Se o comprimento dovarchar(n)
string for maior que 4.000 caracteres, a conversão será paranvarchar(4000)
e o truncamento ocorrerá .
Tipos de dados de literais de string
Se você usar o
N
prefixo e a string tem <=4.000 caracteres, ela será digitada como nvarchar(n)
onde n
é o comprimento da corda. Então N'Foo'
será tratado como nvarchar(3)
por exemplo. Se a string tiver mais de 4.000 caracteres, ela será tratada como nvarchar(max)
Se você não usar o
N
prefixo e a string tem <=8.000 caracteres, ela será digitada como varchar(n)
onde n
é o comprimento da corda. Se mais longo como varchar(max)
Para ambos os itens acima, se o comprimento da string for zero,
n
é definido como 1. Elementos de sintaxe mais recentes.
1. O
CONCAT
função não ajuda aqui DECLARE @A5000 VARCHAR(5000) = REPLICATE('A',5000);
SELECT DATALENGTH(@A5000 + @A5000),
DATALENGTH(CONCAT(@A5000,@A5000));
O acima retorna 8000 para ambos os métodos de concatenação.
2. Tenha cuidado com
+=
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);`
Devoluções
-------------------- --------------------
8000 10000
Observe que
@A
encontrou truncamento. Como resolver o problema que você está enfrentando.
Você está obtendo truncamento porque está concatenando dois não
max
tipos de dados juntos ou porque você está concatenando um varchar(4001 - 8000)
string para um nvarchar
string digitada (mesmo nvarchar(max)
). Para evitar o segundo problema, simplesmente certifique-se de que todos os literais de string (ou pelo menos aqueles com comprimentos no intervalo 4001 - 8000) sejam precedidos por
N
. Para evitar o primeiro problema, altere a atribuição de
DECLARE @SQL NVARCHAR(MAX);
SET @SQL = 'Foo' + 'Bar' + ...;
Para
DECLARE @SQL NVARCHAR(MAX) = '';
SET @SQL = @SQL + N'Foo' + N'Bar'
para que um
NVARCHAR(MAX)
está envolvido na concatenação desde o início (pois o resultado de cada concatenação também será NVARCHAR(MAX)
isso vai se propagar) Evitando truncamento ao visualizar
Certifique-se de ter o modo "resultados para grade" selecionado, então você pode usar
select @SQL as [processing-instruction(x)] FOR XML PATH
As opções do SSMS permitem definir comprimento ilimitado para
XML
resultados. A processing-instruction
bit evita problemas com caracteres como <
aparecendo como <
.