Capisco che sia impostato un massimo di 4000 NVARCHAR(MAX)
La tua comprensione è sbagliata. nvarchar(max)
può memorizzare fino a (e talvolta oltre) 2 GB di dati (1 miliardo di caratteri a doppio byte).
Da nchar e nvarchar nei libri in linea la grammatica è
nvarchar [ ( n | max ) ]
Il |
carattere significa che queste sono alternative. cioè si specifica o n
o il letterale max
.
Se si sceglie di specificare uno specifico, n
questo deve essere compreso tra 1 e 4.000, ma l'utilizzo lo max
definisce come un tipo di dati oggetto di grandi dimensioni (la sostituzione ntext
è deprecata).
Infatti in SQL Server 2008 sembra che per una variabile il limite di 2GB possa essere superato indefinitamente previo 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)
troncerà a 8.000 caratteri.
nvarchar(n) + nvarchar(n)
troncerà a 4.000 caratteri.
varchar(n) + nvarchar(n)
troncerà 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 come varchar(max)
.
varchar(max)
+ nvarchar(n)
non verrà troncato (per <2 GB) e il risultato verrà digitato come nvarchar(max)
.
nvarchar(max)
+ varchar(n)
convertirà prima l' varchar(n)
input in nvarchar(n)
e poi eseguirà la concatenazione. Se la lunghezza della varchar(n)
stringa è maggiore di 4.000 caratteri, verrà eseguito il cast e verrà eseguito il nvarchar(4000)
troncamento .
Tipi di dati di stringhe letterali
Se si utilizza il N
prefisso e la stringa è <= 4.000 caratteri, verrà digitata come nvarchar(n)
dove n
è la lunghezza della stringa. Quindi N'Foo'
sarà trattato come nvarchar(3)
per esempio. Se la stringa è più lunga di 4.000 caratteri, verrà trattata comenvarchar(max)
Se non utilizzi il N
prefisso e la stringa è <= 8.000 caratteri, verrà digitata come varchar(n)
dove n
è la lunghezza della stringa. Se più a lungovarchar(max)
Per entrambi i precedenti, se la lunghezza della stringa è zero, n
viene impostata su 1.
Elementi di sintassi più recenti.
1. La CONCAT
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. Stai attento 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);`
ritorna
-------------------- --------------------
8000 10000
Notare che si è @A
verificato un troncamento.
Come risolvere il problema riscontrato.
Stai ottenendo il troncamento o perché stai concatenando due max
tipi di dati non insieme o perché stai concatenando una varchar(4001 - 8000)
stringa a una nvarchar
stringa digitata (pari nvarchar(max)
).
Per evitare il secondo problema, assicurati semplicemente che tutte le stringhe letterali (o almeno quelle con lunghezze comprese tra 4001 e 8000) siano precedute da N
.
Per evitare il primo problema, modificare l'assegnazione da
DECLARE @SQL NVARCHAR(MAX);
SET @SQL = 'Foo' + 'Bar' + ...;
Per
DECLARE @SQL NVARCHAR(MAX) = '';
SET @SQL = @SQL + N'Foo' + N'Bar'
in modo che un NVARCHAR(MAX)
sia 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 avere selezionato la modalità "risultati su griglia", quindi puoi utilizzarla
select @SQL as [processing-instruction(x)] FOR XML PATH
Le opzioni SSMS consentono di impostare una lunghezza illimitata per i XML
risultati. Il processing-instruction
bit evita problemi con personaggi come <
apparire come <
.