sql >> Databáze >  >> RDS >> Sqlserver

Limity SQL NVARCHAR a VARCHAR

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.

  1. varchar(n) + varchar(n) se zkrátí na 8 000 znaků.
  2. nvarchar(n) + nvarchar(n) se zkrátí na 4 000 znaků.
  3. varchar(n) + nvarchar(n) se zkrátí na 4 000 znaků. nvarchar má vyšší prioritu, takže výsledek je nvarchar(4,000)
  4. [n]varchar(max) + [n]varchar(max) nezkrátí (pro <2 GB).
  5. varchar(max) + varchar(n) se nezkrátí (pro <2 GB) a výsledek bude napsán jako varchar(max) .
  6. varchar(max) + nvarchar(n) se nezkrátí (pro <2 GB) a výsledek bude napsán jako nvarchar(max) .
  7. nvarchar(max) + varchar(n) nejprve převede varchar(n) vstup do nvarchar(n) a poté proveďte zřetězení. Pokud je délka parametru varchar(n) řetězec je delší než 4 000 znaků, přetypování bude na nvarchar(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 &lt; zobrazí se jako &lt; .



  1. Okamžitá inicializace souboru:Dopad během instalace

  2. Získání chyby ORA - 00907 v následující části ON UPDATE

  3. Oracle RAC a sekvence

  4. Obnovte kopii vaší databáze