Jeg forstår, at der er et max. 4000 indstillet for NVARCHAR(MAX)
Din forståelse er forkert. nvarchar(max)
kan gemme op til (og nogle gange mere) 2 GB data (1 milliard dobbeltbyte-tegn).
Fra nchar og nvarchar i Books online er grammatikken
nvarchar [ ( n | max ) ]
|
karakter betyder, at disse er alternativer. dvs. du angiver enten n
eller det bogstavelige max
.
Hvis du vælger at angive en specifik n
så skal dette være mellem 1 og 4.000, men ved at bruge max
definerer det som en datatype for et stort objekt (erstatning for ntext
som er forældet).
Faktisk i SQL Server 2008 ser det ud til, at for en variabel grænsen på 2 GB kan overskrides på ubestemt tid, hvis der er tilstrækkelig plads i tempdb
(Vis her)
Med hensyn til de andre dele af dit spørgsmål
Trunkering ved sammenkædning afhænger af datatype.
varchar(n) + varchar(n)
afkortes med 8.000 tegn.nvarchar(n) + nvarchar(n)
afkortes med 4.000 tegn.varchar(n) + nvarchar(n)
vil afkortes med 4.000 tegn.nvarchar
har højere forrang, så resultatet ernvarchar(4,000)
[n]varchar(max)
+[n]varchar(max)
afkortes ikke (for <2 GB).varchar(max)
+varchar(n)
afkortes ikke (for <2 GB), og resultatet vil blive skrevet somvarchar(max)
.varchar(max)
+nvarchar(n)
afkortes ikke (for <2 GB), og resultatet vil blive skrevet somnvarchar(max)
.nvarchar(max)
+varchar(n)
vil først konverterevarchar(n)
input tilnvarchar(n)
og lav derefter sammenkædningen. Hvis længden af varchar(n)
strengen er større end 4.000 tegn, castet vil være tilnvarchar(4000)
og trunkering vil forekomme .
Datatyper af strengliteraler
Hvis du bruger N
præfiks og strengen er <=4.000 tegn lang den vil blive skrevet som nvarchar(n)
hvor n
er længden af strengen. Så N'Foo'
vil blive behandlet som nvarchar(3)
for eksempel. Hvis strengen er længere end 4.000 tegn vil den blive behandlet som nvarchar(max)
Hvis du ikke bruger N
præfiks og strengen er <=8.000 tegn lang den vil blive skrevet som varchar(n)
hvor n
er længden af strengen. Hvis længere som varchar(max)
For begge ovenstående, hvis længden af strengen er nul, så n
er indstillet til 1.
Nyere syntakselementer.
1. CONCAT
funktion hjælper ikke her
DECLARE @A5000 VARCHAR(5000) = REPLICATE('A',5000);
SELECT DATALENGTH(@A5000 + @A5000),
DATALENGTH(CONCAT(@A5000,@A5000));
Ovenstående returnerer 8000 for begge sammenkædningsmetoder.
2. Vær forsigtig med +=
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);`
Returnerer
-------------------- --------------------
8000 10000
Bemærk at @A
stødt på trunkering.
Sådan løser du det problem, du oplever.
Du får enten trunkering, fordi du sammenkæder to ikke max
datatyper sammen, eller fordi du sammenkæder en varchar(4001 - 8000)
streng til en nvarchar
indtastet streng (selv nvarchar(max)
).
For at undgå det andet problem skal du blot sørge for, at alle strengliteraler (eller i det mindste dem med længder i intervallet 4001 - 8000) er indledt med N
.
For at undgå det første problem skal du ændre opgaven fra
DECLARE @SQL NVARCHAR(MAX);
SET @SQL = 'Foo' + 'Bar' + ...;
Til
DECLARE @SQL NVARCHAR(MAX) = '';
SET @SQL = @SQL + N'Foo' + N'Bar'
så en NVARCHAR(MAX)
er involveret i sammenkædningen fra begyndelsen (da resultatet af hver sammenkædning også vil være NVARCHAR(MAX)
dette vil forplante sig)
Undgå trunkering ved visning
Sørg for, at du har valgt "resultater til gitter"-tilstand, så kan du bruge
select @SQL as [processing-instruction(x)] FOR XML PATH
SSMS-indstillingerne giver dig mulighed for at indstille ubegrænset længde for XML
resultater. processing-instruction
bit undgår problemer med tegn såsom <
vises som <
.