Chápu, že pro
NVARCHAR(MAX)
je nastaveno max. 4000
Vaše chápání je špatné. nvarchar(max)
může uložit až (někdy i více) 2 GB dat (1 miliarda dvoubajtových znaků).
Z nchar a nvarchar v Knihách online je gramatika
nvarchar [ ( n | max ) ]
|
znak znamená, že se jedná o alternativy. tj. určíte buď n
nebo doslovný max
.
Pokud se rozhodnete zadat konkrétní n
pak to musí být mezi 1 a 4 000, ale s použitím max
definuje jej jako datový typ velkého objektu (náhrada za ntext
který je zastaralý).
Ve skutečnosti se v SQL Server 2008 zdá, že pro proměnnou limit 2 GB lze neomezeně překračovat, pokud je v tempdb
dostatek místa (Zde zobrazeno)
Pokud jde o další části vaší otázky
Zkrácení při zřetězení závisí na datovém typu.
varchar(n) + varchar(n)
se zkrátí na 8 000 znaků.nvarchar(n) + nvarchar(n)
se zkrátí na 4 000 znaků.varchar(n) + nvarchar(n)
se zkrátí na 4 000 znaků.nvarchar
má vyšší prioritu, takže výsledek jenvarchar(4,000)
[n]varchar(max)
+[n]varchar(max)
nezkrátí (pro <2 GB).varchar(max)
+varchar(n)
se nezkrátí (pro <2 GB) a výsledek bude napsán jakovarchar(max)
.varchar(max)
+nvarchar(n)
se nezkrátí (pro <2 GB) a výsledek bude napsán jakonvarchar(max)
.nvarchar(max)
+varchar(n)
nejprve převedevarchar(n)
vstup donvarchar(n)
a poté proveďte zřetězení. Pokud je délka parametruvarchar(n)
řetězec je delší než 4 000 znaků, přetypování bude nanvarchar(4000)
a dojde ke zkrácení .
Datové typy řetězcových literálů
Pokud použijete N
prefix a řetězec je <=4 000 znaků dlouhý, zapíše se jako nvarchar(n)
kde n
je délka provázku. Takže N'Foo'
bude považováno za nvarchar(3)
například. Pokud je řetězec delší než 4 000 znaků, bude považován za nvarchar(max)
Pokud nepoužijete N
prefix a řetězec je <=8 000 znaků dlouhý, zapíše se jako varchar(n)
kde n
je délka provázku. Pokud je delší jako varchar(max)
Pro oba výše uvedené, pokud je délka řetězce nula, pak n
je nastaveno na 1.
Novější prvky syntaxe.
1. CONCAT
funkce zde nepomůže
DECLARE @A5000 VARCHAR(5000) = REPLICATE('A',5000);
SELECT DATALENGTH(@A5000 + @A5000),
DATALENGTH(CONCAT(@A5000,@A5000));
Výše uvedené vrátí 8000 pro obě metody zřetězení.
2. Buďte opatrní s +=
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);`
Vrátí
-------------------- --------------------
8000 10000
Všimněte si, že @A
došlo ke zkrácení.
Jak vyřešit problém, se kterým se setkáváte.
Dochází ke zkrácení buď proto, že zřetězujete dva jiné než max
datové typy dohromady nebo proto, že zřetězujete varchar(4001 - 8000)
řetězec na nvarchar
zadaný řetězec (dokonce i nvarchar(max)
).
Chcete-li se vyhnout druhému problému, jednoduše se ujistěte, že všechny řetězcové literály (nebo alespoň ty s délkami v rozsahu 4001 - 8000) mají předponu N
.
Chcete-li se vyhnout prvnímu problému, změňte přiřazení z
DECLARE @SQL NVARCHAR(MAX);
SET @SQL = 'Foo' + 'Bar' + ...;
Komu
DECLARE @SQL NVARCHAR(MAX) = '';
SET @SQL = @SQL + N'Foo' + N'Bar'
takže NVARCHAR(MAX)
je zapojen do zřetězení od začátku (jelikož výsledkem každého zřetězení bude také NVARCHAR(MAX)
toto se bude šířit)
Zabránění zkrácení při prohlížení
Ujistěte se, že máte vybraný režim „výsledky do mřížky“, pak můžete použít
select @SQL as [processing-instruction(x)] FOR XML PATH
Možnosti SSMS umožňují nastavit neomezenou délku XML
Výsledek. processing-instruction
bit zabraňuje problémům se znaky, jako je <
zobrazí se jako <
.