Nvarchar max сколько символов
Перейти к содержимому

Nvarchar max сколько символов

  • автор:

Nvarchar max сколько символов

При создании таблицы для всех ее столбцов необходимо указать определенный тип данных. Тип данных определяет, какие значения могут храниться в столбце, сколько они будут занимать места в памяти.

Язык T-SQL предоставляет множество различных типов. В зависимости от характера значений все их можно разделить на группы.

Числовые типы данных

BIT : хранит значение от 0 до 16. Может выступать аналогом булевого типа в языках программирования (в этом случае значению true соответствует 1, а значению false — 0). При значениях до 8 (включительно) занимает 1 байт, при значениях от 9 до 16 — 2 байта.

TINYINT : хранит числа от 0 до 255. Занимает 1 байт. Хорошо подходит для хранения небольших чисел.

SMALLINT : хранит числа от –32 768 до 32 767. Занимает 2 байта

INT : хранит числа от –2 147 483 648 до 2 147 483 647. Занимает 4 байта. Наиболее используемый тип для хранения чисел.

BIGINT : хранит очень большие числа от -9 223 372 036 854 775 808 до 9 223 372 036 854 775 807, которые занимают в памяти 8 байт.

DECIMAL : хранит числа c фиксированной точностью. Занимает от 5 до 17 байт в зависимости от количества чисел после запятой.

Данный тип может принимать два параметра precision и scale: DECIMAL(precision, scale) .

Параметр precision представляет максимальное количество цифр, которые может хранить число. Это значение должно находиться в диапазоне от 1 до 38. По умолчанию оно равно 18.

Параметр scale представляет максимальное количество цифр, которые может содержать число после запятой. Это значение должно находиться в диапазоне от 0 до значения параметра precision. По умолчанию оно равно 0.

NUMERIC : данный тип аналогичен типу DECIMAL.

SMALLMONEY : хранит дробные значения от -214 748.3648 до 214 748.3647. Предназначено для хранения денежных величин. Занимает 4 байта. Эквивалентен типу DECIMAL(10,4) .

MONEY : хранит дробные значения от -922 337 203 685 477.5808 до 922 337 203 685 477.5807. Представляет денежные величины и занимает 8 байт. Эквивалентен типу DECIMAL(19,4) .

FLOAT : хранит числа от –1.79E+308 до 1.79E+308. Занимает от 4 до 8 байт в зависимости от дробной части.

Может иметь форму опредеения в виде FLOAT(n) , где n представляет число бит, которые используются для хранения десятичной части числа (мантиссы). По умолчанию n = 53.

REAL : хранит числа от –340E+38 to 3.40E+38. Занимает 4 байта. Эквивалентен типу FLOAT(24) .

Примеры числовых столбцов:

Типы данных, представляющие дату и время

DATE : хранит даты от 0001-01-01 (1 января 0001 года) до 9999-12-31 (31 декабря 9999 года). Занимает 3 байта.

TIME : хранит время в диапазоне от 00:00:00.0000000 до 23:59:59.9999999. Занимает от 3 до 5 байт.

Может иметь форму TIME(n) , где n представляет количество цифр от 0 до 7 в дробной части секунд.

DATETIME : хранит даты и время от 01/01/1753 до 31/12/9999. Занимает 8 байт.

DATETIME2 : хранит даты и время в диапазоне от 01/01/0001 00:00:00.0000000 до 31/12/9999 23:59:59.9999999. Занимает от 6 до 8 байт в зависимости от точности времени.

Может иметь форму DATETIME2(n) , где n представляет количество цифр от 0 до 7 в дробной части секунд.

SMALLDATETIME : хранит даты и время в диапазоне от 01/01/1900 до 06/06/2079, то есть ближайшие даты. Занимает от 4 байта.

DATETIMEOFFSET : хранит даты и время в диапазоне от 0001-01-01 до 9999-12-31. Сохраняет детальную информацию о времени с точностью до 100 наносекунд. Занимает 10 байт.

Распространенные форматы дат:

В таком формате двузначные числа от 00 до 49 воспринимаются как даты в диапазоне 2000-2049. А числа от 50 до 99 как диапазон чисел 1950 — 1999.

Month dd, yyyy — July 12, 2017

Распространенные форматы времени:

hh:mi am/pm — 1:21 pm

Строковые типы данных

CHAR : хранит строку длиной от 1 до 8 000 символов. На каждый символ выделяет по 1 байту. Не подходит для многих языков, так как хранит символы не в кодировке Unicode.

Количество символов, которое может хранить столбец, передается в скобках. Например, для столбца с типом CHAR(10) будет выделено 10 байт. И если мы сохраним в столбце строку менее 10 символов, то она будет дополнена пробелами.

VARCHAR : хранит строку. На каждый символ выделяется 1 байт. Можно указать конкретную длину для столбца — от 1 до 8 000 символов, например, VARCHAR(10) . Если строка должна иметь больше 8000 символов, то задается размер MAX, а на хранение строки может выделяться до 2 Гб: VARCHAR(MAX) .

Не подходит для многих языков, так как хранит символы не в кодировке Unicode.

В отличие от типа CHAR если в столбец с типом VARCHAR(10) будет сохранена строка в 5 символов, то в столце будет сохранено именно пять символов.

NCHAR : хранит строку в кодировке Unicode длиной от 1 до 4 000 символов. На каждый символ выделяется 2 байта. Например, NCHAR(15)

NVARCHAR : хранит строку в кодировке Unicode. На каждый символ выделяется 2 байта.Можно задать конкретный размер от 1 до 4 000 символов: . Если строка должна иметь больше 4000 символов, то задается размер MAX, а на хранение строки может выделяться до 2 Гб.

Еще два типа TEXT и NTEXT являются устаревшими и поэтому их не рекомендуется использовать. Вместо них применяются VARCHAR и NVARCHAR соответственно.

Примеры определения строковых столбцов:

Бинарные типы данных

BINARY : хранит бинарные данные в виде последовательности от 1 до 8 000 байт.

VARBINARY : хранит бинарные данные в виде последовательности от 1 до 8 000 байт, либо до 2^31–1 байт при использовании значения MAX (VARBINARY(MAX)).

Еще один бинарный тип — тип IMAGE является устаревшим, и вместо него рекомендуется применять тип VARBINARY.

Остальные типы данных

UNIQUEIDENTIFIER : уникальный идентификатор GUID (по сути строка с уникальным значением), который занимает 16 байт.

TIMESTAMP : некоторое число, которое хранит номер версии строки в таблице. Занимает 8 байт.

CURSOR : представляет набор строк.

HIERARCHYID : представляет позицию в иерархии.

SQL_VARIANT : может хранить данные любого другого типа данных T-SQL.

XML : хранит документы XML или фрагменты документов XML. Занимает в памяти до 2 Гб.

Типы данных Transact-SQL

Все значения в столбце должны быть одного типа данных. (Единственным исключением из этого правила являются значения типа данных SQL_VARIANT.) Используемые в Transact-SQL типы данных можно разбить на следующие категории:

временные типы (даты и/или времени);

прочие типы данных.

Все эти категории данных рассматриваются далее в последующих разделах.

Числовые типы данных

Как и следовало ожидать по их названию, числовые типы данных применяются для представления чисел. Эти типы и их краткое описание приводятся в таблице ниже:

Представляет целочисленные значения длиной в 4 байта в диапазоне от -2 32 до 2 32 — 1. INT — сокращенная форма от INTEGER.

Представляет целочисленные значения длиной в 2 байта в диапазоне от -32 768 до 32 767

Представляет целочисленные значения длиной в 1 байт в диапазоне от 0 до 255

Представляет целочисленные значения длиной в 8 байт в диапазоне от -2 63 до 2 63 — 1

Представляет значения с фиксированной точкой. Аргумент p (precision — точность) указывает общее количество разрядов, а аргумент s (scale — степень) — количество разрядов справа от полагаемой десятичной точки. В зависимости от значения аргумента p, значения decimal сохраняются в 5 до 17 байтах. DEC — сокращенная форма от DECIMAL.

Применяется для представления значений с плавающей точкой. Диапазон положительных значений простирается приблизительно от 2,23E -308 до -1,18E -38. Также может быть представлено и нулевое значение.

Подобно типу REAL, представляет значения с плавающей точкой [(p)]. Аргумент p определяет точность. При значении p < 25 представляемые значения имеют одинарную точность (требуют 4 байта для хранения), а при значении p >= 25 — двойную точность (требуют 8 байтов для хранения).

Используется для представления денежных значений. Значения типа MONEY соответствуют 8-байтовым значениям типа DECIMAL, округленным до четырех разрядов после десятичной точки

Представляет такие же значения, что и тип MONEY, но длиной в 4 байта

Символьные типы данных

Существует два общих вида символьных типов данных. Строки могут представляться однобайтовыми символами или же символами в кодировке Unicode. (В кодировке Unicode для представления одного символа применяется несколько байтов.) Кроме этого, строки могут быть разной длины. В таблице ниже перечислены категории символьных типов данных с их кратким описанием.

Применяется для представления строк фиксированной длины, состоящих из n однобайтовых символов. Максимальное значение n равно 8000. CHARACTER(n) — альтернативная эквивалентная форма CHAR(n). Если n явно не указано, то его значение полагается равным 1.

Используется для представления строки однобайтовых символов переменной длины (0 < n < 8 000). В отличие от типа данных CHAR, количество байтов для хранения значений типа данных VARCHAR равно их действительной длине. Этот тип данных имеет два синонима: CHAR VARYING и CHARACTER VARYING.

Используется для хранения строк фиксированной длины, состоящих из символов в кодировке Unicode. Основная разница между типами данных CHAR и NCHAR состоит в том, что для хранения каждого символа строки типа NCHAR требуется 2 байта, а строки типа CHAR — 1 байт. Поэтому строка типа данных NCHAR может содержать самое большее 4000 символов. Тип NCHAR можно использовать для хранения, например, символов русского алфавита, т.к. однобайтовые кодировки не позволяют делать этого.

Используется для хранения строк переменной длины, состоящих из символов в кодировке Unicode. Для хранения каждого символа строки типа NVARCHAR требуется 2 байта, поэтому строка типа данных NVARCHAR может содержать самое большее 4000 символов.

Тип данных VARCHAR идентичен типу данных CHAR, за исключением одного различия: если содержимое строки CHAR(n) короче, чем n символов, остаток строки заполняется пробелами. А количество байтов, занимаемых строкой типа VARCHAR, всегда равно количеству символов в ней.

Типы данных времени

В языке Transact-SQL поддерживаются следующие временные типы данных:

Типы данных DATETIME и SMALLDATETIME применяются для хранения даты и времени в виде целочисленных значений длиной в 4 и 2 байта соответственно. Значения типа DATETIME и SMALLDATETIME сохраняются внутренне как два отдельных числовых значения. Составляющая даты значений типа DATETIME хранится в диапазоне от 01/01/1753 до 31/12/9999, а соответствующая составляющая значений типа SMALLDATETIME — в диапазоне от 01/01/1900 до 06/06/2079. Составляющая времени хранится во втором 4-байтовом (2-байтовом для значений типа SMALLDATETIME) поле в виде числа трехсотых долей секунды (для DATETIME) или числа минут (для SMALLDATETIME), истекших после полуночи.

Если нужно сохранить только составляющую даты или времени, использование значений типа DATETIME или SMALLDATETIME несколько неудобно. По этой причине в SQL Server были введены типы данных DATE и TIME, в которых хранятся только составляющие даты и времени значений типа DATETIME, соответственно. Значения типа DATE занимают 3 байта, представляя диапазон дат от 01/01/0001 до 31/12/9999. Значения типа TIME занимают 3-5 байт и представляют время с точностью до 100 нс.

Тип данных DATETIME2 используется для представления значений дат и времени с высокой точностью. В зависимости от требований, значения этого типа можно определять разной длины, и занимают они от 6 до 8 байтов. Составляющая времени представляет время с точностью до 100 нс. Этот тип данных не поддерживает переход на летнее время.

Все рассмотренные на данный момент временные типы данных не поддерживают часовые пояса. Тип данных DATETIMEOFFSET имеет составляющую для хранения смещения часового пояса. По этой причине значения этого типа занимают от 6 до 8 байтов. Все другие свойства этого типа данных аналогичны соответствующим свойствам типа данных DATETIME2.

Значения дат в Transact-SQL по умолчанию определены в виде строки формата ‘ммм дд гггг’ (например, ‘Jan 10 1993’), заключенной в одинарные или двойные кавычки. (Но относительный порядок составляющих месяца, дня и года можно изменять с помощью инструкции SET DATEFORMAT. Кроме этого, система поддерживает числовые значения для составляющей месяца и разделители / и -.) Подобным образом, значение времени указывается в 24-часовом формате в виде ‘чч:мм’ (например, ’22:24′).

Язык Transact-SQL поддерживает различные форматы ввода значений типа DATETIME. Как уже упоминалось, каждая составляющая определяется отдельно, поэтому значения дат и времени можно указать в любом порядке или отдельно. Если одна из составляющих не указывается, система использует для него значение по умолчанию. (Значение по умолчанию для времени — 12:00 AM (до полудня).)

Двоичные и битовые типы данных

К двоичным типам данным принадлежат два типа: BINARY и VARBINARY. Эти типы данных описывают объекты данных во внутреннем формате системы и используются для хранения битовых строк. По этой причине значения этих типов вводятся, используя шестнадцатеричные числа.

Значения битового типа bit содержат лишь один бит, вследствие чего в одном байте можно сохранить до восьми значений этого типа. Краткое описание свойств двоичных и битовых типов данных приводится в таблице ниже:

Определяет строку битов фиксированной длины, содержащую ровно n байтов(0 < n < 8000)

Определяет строку битов переменной длины, содержащую до n байтов (0 < n < 8000)

Применяется для хранения логических значений, которые могут иметь три возможных состояния: false, true и null

Тип данных больших объектов

используется для хранения объектов данных размером до 2 Гбайт. Такие объекты обычно применяются для хранения больших объемов текстовых данных и для загрузки подключаемых модулей и аудио- и видеофайлов. В языке Transact-SQL поддерживаются следующие типы данных LOB:

Начиная с версии SQL Server 2005, для обращения к значениям стандартных типов данных и к значениям типов данных LOB применяется одна и та же модель программирования. Иными словами, для работы с объектами LOB можно использовать удобные системные функции и строковые операторы.

В компоненте Database Engine параметр MAX применяется с типами данных VARCHAR, NVARCHAR и VARBINARY для определения значений столбцов переменной длины. Когда вместо явного указания длины значения используется значение длины по умолчанию MAX, система анализирует длину конкретной строки и принимает решение, сохранять ли эту строку как обычное значение или как значение LOB. Параметр MAX указывает, что размер значений столбца может достигать максимального размера LOB данной системы.

Хотя решение о способе хранения объектов LOB принимается системой, настройки по умолчанию можно переопределить, используя системную процедуру sp_tableoption с аргументом LARGE_VALUE_TYPES_OUT_OF_ROW. Если значение этого аргумента равно 1, то данные в столбцах, объявленных с использованием параметра MAX, будут сохраняться отдельно от остальных данных. Если же значение аргумента равно 0, то компонент Database Engine сохраняет все значения размером до 8 060 байт в строке таблицы, как обычные данные, а значения большего размера хранятся вне строки в области хранения объектов LOB.

Начиная с версии SQL Server 2008, для столбцов типа VARBINARY(MAX) можно применять атрибут FILESTREAM, чтобы сохранять данные BLOB (Binary Large OBject — большой двоичный объект) непосредственно в файловой системе NTFS. Основным достоинством этого атрибута является то, что размер соответствующего объекта LOB ограничивается только размером тома файловой системы.

Тип данных UNIQUEIDENTIFIER

Как можно судить по его названию, тип данных UNIQUEIDENTIFIER является однозначным идентификационным номером, который сохраняется в виде 16-байтовой двоичной строки. Этот тип данных тесно связан с идентификатором GUID (Globally Unique Identifier — глобально уникальный идентификатор), который гарантирует однозначность в мировом масштабе. Таким образом, этот тип данных позволяет однозначно идентифицировать данные и объекты в распределенных системах.

Инициализировать столбец или переменную типа UNIQUEIDENTIFIER можно посредством функции NEWID или NEWSEQUENTIALID, а также с помощью строковой константы особого формата, состоящей из шестнадцатеричных цифр и дефисов. Эти функции рассматриваются в следующей статье.

К столбцу со значениями типа данных UNIQUEIDENTIFIER можно обращаться, используя в запросе ключевое слово ROWGUIDCOL, чтобы указать, что столбец содержит значения идентификаторов. (Это ключевое слово не генерирует никаких значений.) Таблица может содержать несколько столбцов типа UNIQUEIDENTIFIER, но только один из них может иметь ключевое слово ROWGUIDCOL.

Тип данных SQL_VARIANT

Тип данных SQL_VARIANT можно использовать для хранения значений разных типов одновременно, таких как числовые значения, строки и даты. (Исключением являются значения типа TIMESTAMP.) Каждое значение столбца типа SQL_VARIANT состоит из двух частей: собственно значения и информации, описывающей это значение. Эта информация содержит все свойства действительного типа данных значения, такие как длина, масштаб и точность.

Для доступа и отображения информации о значениях столбца типа SQL_VARIANT применяется функция SQL_VARIANT_PROPERTY.

Объявлять тип столбца как SQL_VARIANT следует только в том случае, если это действительно необходимо. Например, если столбец предназначается для хранения значений разных типов данных или если при создании таблицы тип данных, которые будут храниться в данном столбце, неизвестен.

Тип данных HIERARCHYID

Тип данных HIERARCHYID используется для хранения полной иерархии. Например, в значении этого типа можно сохранить иерархию всех сотрудников или иерархию папок. Этот тип реализован в виде определяемого пользователем типа CLR, который охватывает несколько системных функций для создания узлов иерархии и работы с ними. Следующие функции, среди прочих, принадлежат к методам этого типа данных: GetLevel(), GetAncestor(), GetDescendant(), Read() и Write().

Тип данных TIMESTAMP

Тип данных TIMESTAMP указывает столбец, определяемый как VARBINARY(8) или BINARY(8) , в зависимости от свойства столбца принимать значения null. Для каждой базы данных система содержит счетчик, значение которого увеличивается всякий раз, когда вставляется или обновляется любая строка, содержащая ячейку типа TIMESTAMP, и присваивает этой ячейке данное значение. Таким образом, с помощью ячеек типа TIMESTAMP можно определить относительное время последнего изменения соответствующих строк таблицы. (ROWVERSION является синонимом TIMESTAMP.)

Само по себе значение, сохраняемое в столбце типа TIMESTAMP, не представляет никакой важности. Этот столбец обычно используется для определения, изменилась ли определенная строка таблицы со времени последнего обращения к ней.

Варианты хранения

Начиная с версии SQL Server 2008, существует два разных варианта хранения, каждый из которых позволяет сохранять объекты LOB и экономить дисковое пространство. Это следующие варианты:

хранение данных типа FILESTREAM;

хранение с использованием разреженных столбцов (sparse columns).

Эти варианты хранения рассматриваются в следующих подразделах.

Хранение данных типа FILESTREAM

Как уже упоминалось ранее, SQL Server поддерживает хранение больших объектов (LOB) посредством типа данных VARBINARY(MAX). Свойство этого типа данных таково, что большие двоичные объекты (BLOB) сохраняются в базе данных. Это обстоятельство может вызвать проблемы с производительностью в случае хранения очень больших файлов, таких как аудио- или видеофайлов. В таких случаях эти данные сохраняются вне базы данных во внешних файлах.

Хранение данных типа FILESTREAM поддерживает управление объектами LOB, которые сохраняются в файловой системе NTFS. Основным преимуществом этого типа хранения является то, что хотя данные хранятся вне базы данных, управляются они базой данных. Таким образом, этот тип хранения имеет следующие свойства:

данные типа FILESTREAM можно сохранять с помощью инструкции CREATE TABLE, а для работы с этими данными можно использовать инструкции для модифицирования данных (SELECT, INSERT, UPDATE и DELETE);

система управления базой данных обеспечивает такой же самый уровень безопасности для данных типа FILESTREAM, как и для данных, хранящихся внутри базы данных.

Разреженные столбцы (sparse columns)

Цель варианта хранения, предоставляемого разреженными столбцами, значительно отличается от цели хранения типа FILESTREAM. Тогда как целью хранения типа FILESTREAM является хранение объектов LOB вне базы данных, целью разреженных столбцов является минимизировать дисковое пространство, занимаемое базой данных.

Столбцы этого типа позволяют оптимизировать хранение столбцов, большинство значений которых равны null. При использовании разреженных столбцов для хранения значений null дисковое пространство не требуется, но, с другой стороны, для хранения значений, отличных от null, требуется дополнительно от 2 до 4 байтов, в зависимости от их типа. По этой причине разработчики Microsoft рекомендуют использовать разреженные столбцы только в тех случаях, когда ожидается, по крайней мере, 20% общей экономии дискового пространства.

Разреженные столбцы определяются таким же образом, как и прочие столбцы таблицы; аналогично осуществляется и обращение к ним. Это означает, что для обращения к разреженным столбцам можно использовать инструкции SELECT, INSERT, UPDATE и DELETE таким же образом, как и при обращении к обычным столбцам. Единственная разница касается создания разреженных столбцов: для определения конкретного столбца разреженным применяется аргумент SPARSE после названия столбца, как это показано в данном примере:

Несколько разреженных столбцов таблицы можно сгруппировать в набор столбцов. Такой набор будет альтернативным способом сохранять значения во всех разреженных столбцах таблицы и обращаться к ним.

Значение NULL

Значение null — это специальное значение, которое можно присвоить ячейке таблицы. Это значение обычно применяется, когда информация в ячейке неизвестна или неприменима. Например, если неизвестен номер домашнего телефона служащего компании, рекомендуется присвоить соответствующей ячейке столбца home_telephone значение null.

Если значение любого операнда любого арифметического выражения равно null, значение результата вычисления этого выражения также будет null. Поэтому в унарных арифметических операциях, если значение выражения A равно null, тогда как +A, так и -A возвращает null. В бинарных выражениях, если значение одного или обоих операндов A и B равно null, тогда результат операции сложения, вычитания, умножения, деления и деления по модулю этих операндов также будет null.

Если выражение содержит операцию сравнения и значение одного или обоих операндов этой операции равно null, результат этой операции также будет null.

Значение null должно отличаться от всех других значений. Для числовых типов данных значение 0 и значение null не являются одинаковыми. То же самое относится и к пустой строке и значению null для символьных типов данных.

Значения null можно сохранять в столбце таблицы только в том случае, если это явно разрешено в определении данного столбца. С другой стороны, значения null не разрешаются для столбца, если в его определении явно указано NOT NULL. Если для столбца с типом данных (за исключением типа TIMESTAMP) не указано явно NULL или NOT NULL, то присваиваются следующие значения:

NULL, если значение параметра ANSI_NULL_DFLT_ON инструкции SET равно on.

NOT NULL, если значение параметра ANSI_NULL_DFLT_OFF инструкции SET равно on.

Если инструкцию set не активировать, то столбец по умолчанию будет содержать значение NOT NULL. (Для столбцов типа TIMESTAMP значения null не разрешаются.)

SQL Server NVARCHAR

Summary: in this tutorial, you will learn how to use the SQL Server NVARCHAR data type to store variable-length, Unicode string data.

Overview of SQL Server NVARCHAR data type

SQL Server NVARCHAR data type is used to store variable-length, Unicode string data. The following shows the syntax of NVARCHAR :

In this syntax, n defines the string length that ranges from 1 to 4,000. If you don’t specify the string length, its default value is 1.

Another way to declare a NVARCHAR column is to use the following syntax:

In this syntax, max is the maximum storage size in bytes which is 2^31-1 bytes (2 GB).

In general, the actual storage size in bytes of a NVARCHAR value is two times the number of characters entered plus 2 bytes.

The ISO synonyms of NVARCHAR are NATIONAL CHAR VARYING or NATIONAL CHARACTER VARYING , so you can use them interchangeably in the variable declaration or column data definition.

VARCHAR vs. NVARCHAR

The following table illustrates the main differences between VARCHAR and NVARCHAR data types:

SQL Server NVARCHAR example

The following statement creates a new table that contains one NVARCHAR column:

In this example, the string length of the NVARCHAR column is one by default.

To change the string length of the val column, you use the ALTER TABLE ALTER COLUMN statement:

The following statement inserts a new string into the val column of the test.sql_server_nvarchar table:

The statement worked as expected because the string value has a length that is less than to the string length defined in the column definition.

The following statement attempts to insert a new string data whose length is greater than the string length of the val column:

SQL Server issued an error and terminated the statement:

To find the number of characters and the storage size in bytes of the values stored in the NVARCHAR column, you use the LEN and DATALENGTH functions as follows:

In this tutorial, you have learned how to use the SQL Server NVARCHAR data type to store variable-length, Unicode data in the database.

SQL Server’s [N]VARCHAR(MAX) and How to Wield It

[N]VARCHAR(MAX) is a data type that was created to replace [N]TEXT. Depending on how many characters you store in this data type, it will react differently to its surroundings. It might be just what you needed or it might be your worst nightmare, so choose wisely. Here’s a run down on this data type.

What is [N]VARCHAR(MAX)?

The [N]VARCHAR(MAX) data type was created to replace [N]TEXT. While NTEXT and TEST, and also IMAGE – not discussed here – are still available, they’re going to get dumped. Microsoft keeps threatening it, they just don’t say when!

How Does it Work?

VARCHAR can only be 8,000 Characters

Your standard VARCHAR data type can be defined as having a max length of 8,000. For NVARCHAR, the max length of 4,000 (because NVARCHARs can hold half the amount of characters than VARCHARs as it takes twice as much space to store them). Any time a VARCHAR is used, it will truncate anything over 8,000 characters.

VARCHAR(MAX) can hold up to 2GB

Now, this baby here *slaps the hood of the data type* is a suped up version of the [N]VARCHAR. VARCHAR(MAX) is not the same as saying VARCHAR(8000), nor is NVARCHAR(MAX) the same as saying NVARCHAR(4000). The MAX refers to the ability to store 2^31-1 bytes (or 2^30-1 characters for NVARCHAR), or 2GB. This data type can hold up to TWO GIGABYTES.

What’s it Going to Cost Me?

Some More Space

Now, you could define all your fields as a VARCHAR(MAX), but it’s not a good idea. Any VARCHAR(MAX) field with any data on it gets another 24 bytes attached, just for being MAX. That 24 bytes counts against your row max length total of 8,060 bytes. So, if you have a field that you expect to be 10 characters long and you make it a VARCHAR(MAX), it will be a total of 34 bytes. A VARCHAR(10) data type will still be 10 bytes. An NVARCHAR(MAX) field holding that same field will be 44 bytes, while an NVARCHAR(10) will only be 20 bytes. So, go easy on the MAX.

If you fill that VARCHAR(MAX) up enough, instead of the data being in the row, it’s going to be moved “out of row” – stored in it’s own virtual row with the original row storing a pointer.

Some More Time

When you insert a 2GB value into a VARCHAR(MAX) field, it’s going to take some time. It is going to fill up the datapage that your row is in, and then it’s going to have to just go with a pointer and put all that data into its own row and possibly into it’s own data page.

Specify the Data Type Every Time you Use It

Also, any time you are working with a VARCHAR(MAX), you need to specify that it is a VARCHAR(MAX), or else it’s going to be truncated to 8,000 characters. Notice in the REPLICATE statements used in the examples how the character to replicate is cast to a VARCHAR(MAX). If you don’t do that, it will only create an 8,000-length string.

The other cost is your usual functions aren’t going to work.

Otherwise, Your Usual Functions Might Not Work

Here’s an example. Notice that TestSmallMaxVal and TestMaxVal are both declared as VARCHAR(MAX). When I insert the records into the Test table, I am using REPLICATE so I don’t have two type out two million letter As. (I know, I know… no dedication to the craft.) For the TestSmallMaxVal I just say, “give me two million letter As.” For TestMaxVal, I say, “give me two million VARCHAR(MAX)-type letter As.”

Your results will be from the LEN selects will be as follows:

TestVal testSmallMaxLen testMaxLen
A 8000 2000000000

What happened with TestSmallMaxVal? It was treated as a VARCHAR, and VARCHARs can only be 8,000 characters in length. The rest is automatically truncated.

Use VARCHAR(MAX) if you need to store 2GB, or at least more than 8,000 characters in a field. Otherwise, don’t. When you do use it, make sure you always CONVERT to VARCHAR(MAX) so you don’t get your VARCHARs truncated.

If this article was helpful, Like It or Share It! If you have a question, Ask It!

References

Read some more about [N]VARCHAR(MAX) in the following articles from Microsoft Docs linked below.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *