Comprendo che è stato impostato un massimo di 4000 per NVARCHAR(MAX)
La tua comprensione è sbagliata. nvarchar(max)
può memorizzare fino a (e talvolta oltre) 2 GB di dati (1 miliardo di caratteri a byte doppio).
Da nchar e nvarchar in Libri online la grammatica è
nvarchar [ ( n | max ) ]
Il |
carattere significa che queste sono alternative. cioè specifichi uno dei due n
o il letterale max
.
Se scegli di specificare un n
specifico quindi questo deve essere compreso tra 1 e 4.000 ma utilizzando max
lo definisce come un tipo di dati di oggetti di grandi dimensioni (in sostituzione di ntext
che è deprecato).
Infatti in SQL Server 2008 sembra che per una variabile il limite di 2 GB può essere superato indefinitamente in base allo spazio sufficiente in tempdb
(Mostrato qui)
Per quanto riguarda le altre parti della tua domanda
Il troncamento durante la concatenazione dipende dal tipo di dati.
varchar(n) + varchar(n)
verrà troncato a 8.000 caratteri.nvarchar(n) + nvarchar(n)
troncherà a 4.000 caratteri.varchar(n) + nvarchar(n)
troncherà a 4.000 caratteri.nvarchar
ha una precedenza maggiore, quindi il risultato ènvarchar(4,000)
[n]varchar(max)
+[n]varchar(max)
non verrà troncato (per <2 GB).varchar(max)
+varchar(n)
non verrà troncato (per <2 GB) e il risultato verrà digitato comevarchar(max)
.varchar(max)
+nvarchar(n)
non verrà troncato (per <2 GB) e il risultato verrà digitato comenvarchar(max)
.nvarchar(max)
+varchar(n)
convertirà prima ilvarchar(n)
inseriscinvarchar(n)
e poi fai la concatenazione. Se la lunghezza divarchar(n)
la stringa è maggiore di 4.000 caratteri il cast sarà innvarchar(4000)
e si verificherà un troncamento .
Tipi di dati di letterali stringa
Se usi il N
prefisso e la stringa è lunga <=4.000 caratteri verrà digitata come nvarchar(n)
dove n
è la lunghezza della stringa. Quindi N'Foo'
verrà trattato come nvarchar(3)
Per esempio. Se la stringa è più lunga di 4.000 caratteri verrà trattata come nvarchar(max)
Se non usi il N
prefisso e la stringa è lunga <=8.000 caratteri verrà digitata come varchar(n)
dove n
è la lunghezza della stringa. Se più lungo come varchar(max)
Per entrambi i precedenti se la lunghezza della stringa è zero allora n
è impostato su 1.
Elementi di sintassi più recenti.
1. Il CONCAT
la funzione non aiuta qui
DECLARE @A5000 VARCHAR(5000) = REPLICATE('A',5000);
SELECT DATALENGTH(@A5000 + @A5000),
DATALENGTH(CONCAT(@A5000,@A5000));
Quanto sopra restituisce 8000 per entrambi i metodi di concatenazione.
2. Fai attenzione 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);`
Resi
-------------------- --------------------
8000 10000
Nota che @A
ha riscontrato un troncamento.
Come risolvere il problema che stai riscontrando.
Stai ricevendo il troncamento perché stai concatenando due non max
tipi di dati insieme o perché stai concatenando un varchar(4001 - 8000)
stringa in un nvarchar
stringa digitata (anche nvarchar(max)
).
Per evitare il secondo problema, assicurati semplicemente che tutte le stringhe letterali (o almeno quelle con lunghezze nell'intervallo 4001 - 8000) siano precedute da N
.
Per evitare il primo problema, cambia il compito da
DECLARE @SQL NVARCHAR(MAX);
SET @SQL = 'Foo' + 'Bar' + ...;
A
DECLARE @SQL NVARCHAR(MAX) = '';
SET @SQL = @SQL + N'Foo' + N'Bar'
in modo che un NVARCHAR(MAX)
è coinvolto nella concatenazione dall'inizio (poiché il risultato di ogni concatenazione sarà anche NVARCHAR(MAX)
questo si propagherà)
Evitare il troncamento durante la visualizzazione
Assicurati di aver selezionato la modalità "risultati sulla griglia", quindi puoi utilizzare
select @SQL as [processing-instruction(x)] FOR XML PATH
Le opzioni SSMS ti consentono di impostare una lunghezza illimitata per XML
risultati. Le processing-instruction
bit evita problemi con caratteri come <
visualizzato come <
.