Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

SQL NVARCHAR и VARCHAR граници

Разбирам, че има 4000 максимален набор за NVARCHAR(MAX)

Вашето разбиране е погрешно. nvarchar(max) може да съхранява до (а понякога и повече) 2GB данни (1 милиард двойни байтови знака).

От nchar и nvarchar в Books online граматиката е

nvarchar [ ( n | max ) ]

| характер означава, че това са алтернативи. т.е. посочвате и двете n или литералът max .

Ако изберете да посочите конкретен n тогава това трябва да е между 1 и 4000, но с помощта на max го дефинира като тип данни за голям обект (замяна на ntext който е отхвърлен).

Всъщност в SQL Server 2008 изглежда, че за променлива ограничението от 2 GB може да бъде надвишено за неопределено време при условие на достатъчно място в tempdb (Показано тук)

Относно другите части на въпроса ви

Отрязването при конкатенация зависи от типа данни.

  1. varchar(n) + varchar(n) ще се съкрати на 8000 знака.
  2. nvarchar(n) + nvarchar(n) ще се съкрати на 4000 знака.
  3. varchar(n) + nvarchar(n) ще се съкрати на 4000 знака. nvarchar има по-висок приоритет, така че резултатът е nvarchar(4,000)
  4. [n]varchar(max) + [n]varchar(max) няма да се съкращава (за <2GB).
  5. varchar(max) + varchar(n) няма да се съкращава (за <2GB) и резултатът ще бъде въведен като varchar(max) .
  6. varchar(max) + nvarchar(n) няма да се съкращава (за <2GB) и резултатът ще бъде въведен като nvarchar(max) .
  7. nvarchar(max) + varchar(n) първо ще преобразува varchar(n) въведете в nvarchar(n) и след това направете конкатенацията. Ако дължината на varchar(n) низът е по-голям от 4000 знака, прехвърлянето ще бъде към nvarchar(4000) и ще настъпи съкращаване .

Типове данни на низови литерали

Ако използвате N префикс и низът е с дължина <=4000 знака, той ще бъде въведен като nvarchar(n) където n е дължината на низа. Така че N'Foo' ще се третира като nvarchar(3) например. Ако низът е по-дълъг от 4000 знака, той ще се третира като nvarchar(max)

Ако не използвате N префикс и низът е с дължина <=8000 знака, той ще бъде въведен като varchar(n) където n е дължината на низа. Ако е по-дълго като varchar(max)

И за двете по-горе, ако дължината на низа е нула, тогава n е настроен на 1.

По-нови елементи на синтаксиса.

1. CONCAT функцията не помага тук

DECLARE @A5000 VARCHAR(5000) = REPLICATE('A',5000);

SELECT DATALENGTH(@A5000 + @A5000), 
       DATALENGTH(CONCAT(@A5000,@A5000));

Горното връща 8000 и за двата метода на конкатенация.

2. Внимавайте с +=

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);`

Връща

-------------------- --------------------
8000                 10000

Обърнете внимание, че @A възникна отрязване.

Как да разрешите проблема, който изпитвате.

Получавате съкращаване или защото конкатенирате две не max типове данни заедно или защото конкатенирате varchar(4001 - 8000) низ към nvarchar въведен низ (дори nvarchar(max) ).

За да избегнете втория проблем, просто се уверете, че всички низови литерали (или поне тези с дължини в диапазона 4001 - 8000) са предварителни с N .

За да избегнете първия проблем, променете заданието от

DECLARE @SQL NVARCHAR(MAX);
SET @SQL = 'Foo' + 'Bar' + ...;

До

DECLARE @SQL NVARCHAR(MAX) = ''; 
SET @SQL = @SQL + N'Foo' + N'Bar'

така че NVARCHAR(MAX) участва в конкатенацията от самото начало (като резултатът от всяка конкатенация също ще бъде NVARCHAR(MAX) това ще се разпространи)

Избягване на съкращаване при преглед

Уверете се, че сте избрали режим "резултати към мрежа", след което можете да използвате

select @SQL as [processing-instruction(x)] FOR XML PATH 

Опциите за SSMS ви позволяват да зададете неограничена дължина за XML резултати. processing-instruction bit избягва проблеми със знаци като &lt; показва се като &lt; .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL DELETE с INNER JOIN

  2. SQL Server:използвайте параметър в CREATE DATABASE

  3. Как да върнете Unicode стойността за даден символ в SQL Server – UNICODE()

  4. Преобразувайте „datetimeoffset“ в „time“ в SQL Server (T-SQL примери)

  5. Изходна клауза на SQL Server в скаларна променлива