Когда nvarchar (Max) = nvarchar (4000)? - PullRequest
3 голосов
/ 29 марта 2019

На SO и других сайтах имеется несколько сообщений, в которых четко указано, что максимальная длина nvarchar(max) составляет 2 ГБ. Тем не менее, я вижу также много путаницы в Интернете и в реальной жизни, что на самом деле это 8000/4000 в Юникоде.

Я хотел бы знать, что может изменить этот факт, или, возможно, привести кого-то к ложному предположению.

Некоторые предложения / частичные ответы, которые я уже собрал:

  1. Существуют ли более старые версии SQL Server, которые поддерживают максимум 4000?
  2. При назначении nvarchar(max) переменной / столбца для объединения компонентов не максимального размера, мы должны явно преобразовать все в nvarchar(max)? Вот что-то, демонстрирующее странный пример, когда функция, возвращающая текст, требует преобразования, тогда как N для литерала можно опустить:

    declare @s nvarchar(max) 
    select @s = convert(nvarchar(max), replicate('.', 8000)) + N'Hi!'
    select len(@s) -- returns 8003
    
    declare @s nvarchar(max) 
    select @s = replicate('.', 8000) + N'Hi!' 
    select len(@s) -- returns 4000
    
    declare @s nvarchar(max) 
    select @s = convert(nvarchar(max), replicate('.', 8000)) + 'Hi!' 
    select len(@s) -- returns 8003
    
  3. Есть ли способы отключить функциональность? sp_tableoption @OptionName=large value types out of row или OBJECTPROPERTY(id,'TableTextInRowLimit') имеет какое-либо отношение к этому?

    Разъяснение : Моя цель не в том, чтобы использовать эту функцию, а знать о ее существовании, которое, возможно, действительно использовалось пользователем с более высокими привилегиями, что помешает me используя максимальный размер.

  4. Любые другие пункты с радостью приветствуем

1 Ответ

3 голосов
/ 29 марта 2019

Здесь есть несколько моментов, поскольку я не могу вписаться в комментарий.

  1. Да.(n)varchar(MAX) был введен в SQL Server 2005 .Ранее вам приходилось использовать text, ntext и image для varchar(MAX), nvarchar(MAX) и varbinary(MAX).Старый тип данных уже давно устарел, и вы не должны его использовать.
  2. При объединении данных приоритет типа данных используется для определения окончательного типа данных.Когда задействованы длины, используются объединенные значения длин (A varchar(10) и объединенная varchar(100) вернут varchar(110). Однако обратите внимание, что для достижения длины MAX, по крайней мере, одинстрока должна быть (n)varchar(MAX). SELECT REPLICATE(N'A',3000) + REPLICATE(N'A',3000) AS S вернет строку из 4000 символов. + (Конкатенация строк) (Transact-SQL) - Примечания :

    Если результат конкатенациидлина строк превышает 8 000 байт, результат усекается, однако, если хотя бы одна из сцепленных строк относится к типу большого значения, усечение не происходит.

  3. Отключить какие функции?Использование (n)varchar(MAX)? Зачем? Если вы хотите запретить людям, использующим тип данных, остановите их, используя (n)text и image. На самом деле, вы не можете остановить использование типа данных. Возможно, вы могли быполучить "умный" с триггерами DDL, но я советую против этого.Чтобы ответить на изменения, sp_tableoption нельзя использовать, чтобы остановить кого-либо, использующего тип данных MAX no;мой вышеупомянутый пункт стоит.Цитировать документацию ( sp_tableoption (Transact-SQL) - Аргументы :

    Типы больших значений вне строки: 1 = varchar(max), nvarchar(max), varbinary(max), xml и столбцы большого пользовательского типа (UDT) в таблице хранятся вне строки с 16-байтовым указателем на корень.0 = varchar(max), nvarchar(max), varbinary(max), xml и большие значения UDT сохраняются непосредственно в строке данных, до предела 8000 байт и до тех пор, пока значение может поместиться в записи.Если значение не помещается в записи, указатель сохраняется в строке, а остальное хранится вне строки в пространстве хранения больших объектов.0 является значением по умолчанию.Большой пользовательский тип (UDT) применяется к: SQL Server 2008 - SQL Server 2017.Используйте параметр TEXTIMAGE_ON CREATE TABLE, чтобы указать место для хранения больших типов данных.

  4. Слишком широк для SO.
...