Я розумію, що існує 4000 максимум для NVARCHAR(MAX)
Ваше розуміння неправильне. nvarchar(max)
може зберігати до (та інколи) 2 Гб даних (1 млрд двобайтових символів).
Із nchar і nvarchar у Книгах онлайн граматика
nvarchar [ ( n | max ) ]
На |
характер означає , що ці альтернативи. тобто вказати або n
або буквальним max
.
Якщо ви вирішите вказати конкретний, n
то це повинно бути від 1 до 4 000, але використання max
визначає його як великий тип даних об'єкта (заміна на ntext
який застаріла).
Насправді в SQL Server 2008 здається, що для змінної ліміт 2 Гб може бути перевищений на невизначений термін за умови достатнього місця в tempdb
( Показано тут )
Щодо інших частин вашого питання
Скорочення при об'єднанні залежить від типу даних.
varchar(n) + varchar(n)
скорочується на 8000 символів.
nvarchar(n) + nvarchar(n)
скорочується на 4000 символів.
varchar(n) + nvarchar(n)
скорочується на 4000 символів. nvarchar
має вищий пріоритет, тому результат єnvarchar(4,000)
[n]varchar(max)
+ [n]varchar(max)
не врізається (для <2 Гб).
varchar(max)
+ varchar(n)
не врізається (для <2 Гб), і результат буде набрано як varchar(max)
.
varchar(max)
+ nvarchar(n)
не врізається (для <2 Гб), і результат буде набрано як nvarchar(max)
.
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'
таким чином, що an NVARCHAR(MAX)
залучається до конкатенації з самого початку (як результат кожного конкатенації також буде NVARCHAR(MAX)
це поширюватися)
Уникаючи усікання під час перегляду
Переконайтесь, що у вас вибрано режим "результати на сітку", щоб потім можна було користуватися
select @SQL as [processing-instruction(x)] FOR XML PATH
Параметри SSMS дозволяють встановлювати необмежену довжину для XML
результатів. processing-instruction
Біт дозволяє уникнути проблем з символами , такими як <
показ , як <
.