Какие типы данных не поддерживают null значения sql
Перейти к содержимому

Какие типы данных не поддерживают null значения sql

  • автор:

Обработка значений NULL

Значение NULL в реляционной базе данных используется, если значение в столбце неизвестно или отсутствует. NULL не является ни пустой строкой (для типов данных character или datetime), ни нулевым значением (для числовых типов данных). В спецификации ANSI SQL-92 указано, что значение NULL должно быть одинаковым для всех типов данных, чтобы все значения NULL обрабатывались согласованно. Пространство имен System.Data.SqlTypes обеспечивает семантику со значением NULL, реализуя интерфейс INullable. Каждый из типов данных в System.Data.SqlTypes имеет собственное свойство IsNull и значение Null , которое может быть назначено экземпляру этого типа данных.

В версиях .NET Framework 2.0 и .NET Core 1.0 появилась поддержка типов, допускающих значение NULL, что позволяет программистам расширять тип значения для представления всех значений базового типа. Эти типы CLR, допускающие значение NULL, представляют экземпляр структуры Nullable. Эта возможность особенно полезна, если типы значений упакованы и распакованы, что обеспечивает улучшенную совместимость с типами объектов. Типы CLR, допускающие значение NULL, не предназначены для хранения значений NULL базы данных, так как значение NULL ANSI SQL не работает так же, как ссылка на null (или Nothing в Visual Basic). Для работы со значениями NULL в базе данных ANSI SQL используйте значения NULL System.Data.SqlTypes вместо Nullable. Дополнительные сведения о работе на C# с типами CLR, допускающими значения NULL, см. в этой статье.

Значения NULL и логика трех значений

Разрешение значений NULL в определениях столбцов вводит в приложение логику трех значений. Результатом сравнения может быть одно из трех условий:

Так как значение NULL считается неизвестным, два значения NULL, сравниваемые друг с другом, не считаются равными. В выражениях, использующих арифметические операторы, если какой-либо из операндов имеет значение NULL, результат также равен NULL.

Значения NULL и SqlBoolean

При сравнении между любыми типами System.Data.SqlTypes будет возвращаться значение SqlBoolean. Функция IsNull для каждого типа SqlType возвращает SqlBoolean и может использоваться для проверки на наличие значений NULL. В следующих таблицах истинности показано, как работают операторы AND, OR и NOT при наличии значения NULL. (T = true, F = false и U = неизвестно или NULL.)

Основные сведения о параметре ANSI_NULLS

System.Data.SqlTypes предоставляет ту же семантику, что и при установке параметра ANSI_NULLS в SQL Server. Все арифметические операторы (+, -, *, /, %), битовые операции (~, &, |) и большинство функций возвращают NULL, если какие-либо из операндов или аргументов равны NULL, за исключением операндов или аргументов для свойства IsNull .

Стандарт ANSI SQL-92 не поддерживает columnName = NULL в предложении WHERE. В SQL Server параметр ANSI_NULLS управляет допустимостью значений NULL по умолчанию в базе данных и вычислением сравнений со значениями NULL. Если параметр ANSI_NULLS включен (по умолчанию), то при проверке на наличие значений NULL в выражениях должен использоваться оператор IS NULL. Например, результатом следующего сравнения всегда является неизвестность при включенном параметре ANSI_NULLS:

colname > NULL 

Сравнение с переменной, содержащей значение NULL, также приводит к неизвестному результату:

colname > @MyVariable 

Для тестирования на значение NULL используются предикаты IS NULL и IS NOT NULL. Это может усложнить предложение WHERE. Например, столбец TerritoryID в таблице AdventureWorks Customer допускает значения NULL. Если инструкция SELECT используется для тестирования на значения NULL в дополнение к другим, она должна включать предикат IS NULL:

SELECT CustomerID, AccountNumber, TerritoryID FROM AdventureWorks.Sales.Customer WHERE TerritoryID IN (1, 2, 3) OR TerritoryID IS NULL 

Если в SQL Server параметр ANSI_NULLS отключен, можно создать выражения, которые используют оператор равенства для сравнения со значением NULL. Однако нельзя запретить другим подключениям задавать параметры NULL для этого подключения. Использование параметра IS NULL для проверки на наличие значений NULL всегда работает, независимо от установленного значения ANSI_NULLS для подключения.

Установка ANSI_NULLS OFF не поддерживается в DataSet , который всегда соответствует стандарту ANSI SQL-92 для обработки значений NULL в System.Data.SqlTypes.

Присвоение значений NULL

Значения NULL являются специальными, и их семантика хранения и назначения различается в разных системах типов и системах хранения. Dataset предназначен для использования с различными системами типов и хранения.

В этом разделе описывается семантика значений NULL для присвоения значений NULL для DataColumn в DataRow в различных системах типов.

DBNull.Value
Это назначение допустимо для любого типа DataColumn . Если тип реализует INullable , DBNull.Value приводится к соответствующему строго типизированному значению NULL.

SqlType.Null
Все типы данных System.Data.SqlTypes реализуют INullable . Если строго типизированное значение NULL может быть преобразовано в тип данных столбца с помощью операторов неявного приведения, то назначение должно быть принятым. Иначе будет вызвано исключение недопустимого приведения.

null
Если значение NULL является допустимым для указанного типа данных DataColumn , оно приводится к соответствующему значению DbNull.Value или Null , связанному с типом INullable ( SqlType.Null ).

derivedUdt.Null
Для столбцов пользовательского типа значения NULL всегда хранятся в зависимости от типа, связанного с DataColumn . Рассмотрим случай пользовательского типа, связанного с DataColumn , который не реализует INullable в отличие от своего подкласса. В этом случае, если назначено строго типизированное значение NULL, связанное с производным классом, оно сохраняется как нетипизированное значение DbNull.Value , так как хранилище значений NULL всегда согласуется с типом данных DataColumn.

В настоящее время структура Nullable или Nullable не поддерживается в DataSet .

Назначение нескольких столбцов (строк)

DataTable.Add , DataTable.LoadDataRow или другие API-интерфейсы, принимающие массив ItemArray, который сопоставляется со строкой, сопоставляют значение NULL со значением по умолчанию DataColumn. Если объект в массиве содержит DbNull.Value или строго типизированный аналог, применяются те же правила, которые описаны выше.

Кроме того, следующие правила применяются к экземпляру назначений NULL DataRow.[«columnName»] :

  • Используемое по умолчанию значение default является DbNull.Value для всех столбцов, за исключением строго типизированных нулевых столбцов с допустимыми строго типизированными значениями NULL.
  • Значения NULL никогда не записываются во время сериализации в XML-файлы (как в xsi:nil).
  • Все значения, в том числе по умолчанию, отличные от NULL, всегда записываются при сериализации в XML. Это отличается от семантики XSD/XML, где значение NULL (xsi: nil) является явным, а значение по умолчанию — неявным (если отсутствует в XML, то проверяющее средство синтаксического анализа может получить его из связанной схемы XSD). Обратное верно для DataTable : значение NULL является неявным, а значение по умолчанию — явным.
  • Всем отсутствующим значениям столбцов для строк, считываемых из входных данных XML, присваивается значение NULL. Строкам, созданным с помощью NewRow или аналогичных методов, присваивается значение по умолчанию DataColumn.
  • Метод IsNull возвращает true как для DbNull.Value , так и для INullable.Null .

Присвоение значений NULL для SqlTypes

Значение по умолчанию для любого экземпляра System.Data.SqlTypes— NULL.

Значения NULL в System.Data.SqlTypes относятся к определенному типу и не могут быть представлены одним значением, таким как DbNull . Чтобы проверить на наличие значений NULL, используйте свойство IsNull .

Значения NULL могут быть назначены DataColumn, как показано в следующем примере кода. Вы можете напрямую назначить значения NULL для переменных SqlTypes без запуска исключения.

Пример

В следующем примере кода показано создание DataTable с двумя столбцами, определенными как SqlInt32 и SqlString. Код добавляет одну строку известных значений, одну строку значений NULL, а затем выполняет итерацию по DataTable, присваивая значения переменным и отображая выходные данные в окне консоли.

using Microsoft.Data.SqlClient; using System.Data.SqlTypes; class Program < static void Main() < WorkWithSqlNulls(); Console.ReadLine(); >static private void WorkWithSqlNulls() < DataTable table = new DataTable(); // Specify the SqlType for each column. DataColumn idColumn = table.Columns.Add("ID", typeof(SqlInt32)); DataColumn descColumn = table.Columns.Add("Description", typeof(SqlString)); // Add some data. DataRow nRow = table.NewRow(); nRow["ID"] = 123; nRow["Description"] = "Side Mirror"; table.Rows.Add(nRow); // Add null values. nRow = table.NewRow(); nRow["ID"] = SqlInt32.Null; nRow["Description"] = SqlString.Null; table.Rows.Add(nRow); // Initialize variables to use when // extracting the data. SqlBoolean isColumnNull = false; SqlInt32 idValue = SqlInt32.Zero; SqlString descriptionValue = SqlString.Null; // Iterate through the DataTable and display the values. foreach (DataRow row in table.Rows) < // Assign values to variables. Note that you // do not have to test for null values. idValue = (SqlInt32)row["ID"]; descriptionValue = (SqlString)row["Description"]; // Test for null value in ID column. isColumnNull = idValue.IsNull; // Display variable values in console window. Console.Write("isColumnNull=, Description=", isColumnNull, idValue, descriptionValue); Console.WriteLine(); > > > 

В этом примере отображаются следующие результаты:

isColumnNull=False, Description=Side Mirror isColumnNull=True, Description=Null 

Сравнение значений NULL с SqlTypes и типами CLR

При сравнении значений NULL важно понимать разницу между тем, как метод Equals вычисляет значения NULL в System.Data.SqlTypes по сравнению с тем, как он работает с типами CLR. Все методы System.Data.SqlTypes Equals используют семантику базы данных для вычисления значений NULL. Если одно или оба значения являются NULL, результатом сравнения будет NULL. С другой стороны, при использовании метода Equals CLR для двух System.Data.SqlTypes вернется значение true, если оба значения соответствуют NULL. Это отражает разницу между использованием метода экземпляра, такого как метод String.Equals CLR, и использованием статического или общего метода SqlString.Equals .

В следующем примере показана разница результатов между методами SqlString.Equals и String.Equals , если каждому из них передается пара значений NULL, а затем пара пустых строк.

using System.Data.SqlTypes; namespace SqlNullsCS < class Program < static void Main() < CompareNulls(); Console.ReadLine(); >private static void CompareNulls() < // Create two new null strings. SqlString a = new SqlString(); SqlString b = new SqlString(); // Compare nulls using static/shared SqlString.Equals. Console.WriteLine("SqlString.Equals shared/static method:"); Console.WriteLine(" Two nulls=", SqlStringEquals(a, b)); // Compare nulls using instance method String.Equals. Console.WriteLine(); Console.WriteLine("String.Equals instance method:"); Console.WriteLine(" Two nulls=", StringEquals(a, b)); // Make them empty strings. a = ""; b = ""; // When comparing two empty strings (""), both the shared/static and // the instance Equals methods evaluate to true. Console.WriteLine(); Console.WriteLine("SqlString.Equals shared/static method:"); Console.WriteLine(" Two empty strings=", SqlStringEquals(a, b)); Console.WriteLine(); Console.WriteLine("String.Equals instance method:"); Console.WriteLine(" Two empty strings=", StringEquals(a, b)); > private static string SqlStringEquals(SqlString string1, SqlString string2) < // SqlString.Equals uses database semantics for evaluating nulls. string returnValue = SqlString.Equals(string1, string2).ToString(); return returnValue; >private static string StringEquals(SqlString string1, SqlString string2) < // String.Equals uses CLR type semantics for evaluating nulls. string returnValue = string1.Equals(string2).ToString(); return returnValue; >> > 

Получается следующий вывод:

SqlString.Equals shared/static method: Two nulls=Null String.Equals instance method: Two nulls=True SqlString.Equals shared/static method: Two empty strings=True String.Equals instance method: Two empty strings=True 

Дальнейшие действия

Типы данных 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.

Используется для хранения строк фиксированной длины, состоящих из символов в кодировке 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;
  • DATE;
  • TIME;
  • DATETIME2;
  • DATETIMEOFFSET.

Типы данных 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:

  • VARCHAR(MAX);
  • NVARCHAR(MAX);
  • VARBINARY(MAX).

Начиная с версии 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 после названия столбца, как это показано в данном примере:

имя_столбца тип_данных 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-Ex blog

Логический (булев) тип данных отсутствует в SQL Server. Другие базы данных, подобные Oracle и MySQL, поддерживают логический тип данных, который принимает значения TRUE и FALSE.

SQL Server использует тип данных Bit, который принимает значения 0, 1 и NULL, которые могут использоваться вместо значений TRUE, FALSE и NULL. Здесь мы рассмотрим несколько примеров на вставку и выборку этих значений.

Что это за тип данных bit?

Этот тип данных может хранить 3 значения, 1, 0 и NULL. Этот тип данных более эффективен, чем тип данных Boolean, используемый другим СУБД, поскольку он использует только один бит для хранения данных. Давайте рассмотрим примеры его использования.

Примеры логического типа в SQL Server

Следующий пример создаст переменную с именем myBoolean типом данных bit. Затем мы установим для переменной значение true и посмотрим результаты.

declare @myBoolean bit 
set @myBoolean='true'
select @myBoolean result

Заметьте, что когда мы выбираем это значение, то выводится 1, означающее true.

Аналогично вы можете установить булево значение в false.

declare @myBoolean bit 
set @myBoolean='false'
select @myBoolean result

Наоборот, и как лучшая практика, вы можете присваивать числа этой переменной. Следующий пример присвоит переменной myBoolean значение 1, а не true. Это предпочтительный вариант.

declare @myBoolean bit 
set @myBoolean=1
select @myBoolean result

Вместо значения false мы присваиваем значение 0.

declare @myBoolean bit 
set @myBoolean=0
select @myBoolean result

Резюмируя сказанное, вы можете присваивать битовой переменной значения 0, 1 или использовать ‘TRUE’ и ‘FALSE’.

Наконец, вы можете установить переменную bit в значение NULL, если это необходимо. В следующем примере переменной @myBoolean присваивается значение NULL.

declare @myBoolean bit 
set @myBoolean=NULL
select @myBoolean result

Как заменить значения 0, 1 на значения true или false

Как вы уже видели, тип bit показывает 0 и 1 вместо TRUE и FALSE. Как можно заменить значения 0 и 1 на TRUE и FALSE?

Следующий пример демонстрирует как это сделать. Мы будем использовать оператор CASE для замены значений. Вот этот пример.

declare @myBoolean bit 
set @myBoolean='TRUE'
select
case
WHEN @myBoolean=1 then 'TRUE'
WHEN @myBoolean=0 then 'FALSE'
ELSE NULL
end as result

Код выполняет следующее. Если значение равно 1, то будет возвращаться TRUE. Если значение переменной равно 0, то возвращается FALSE. В противном случае возвращается NULL.

Как создать таблицу со столбцом типа данных bit

В следующем примере создается таблица с именем myBooleanTable и двумя столбцами. Столбец ID имеет тип INTEGER, а столбец ispair — тип данных BIT.

create table myBooleanTable 
(
id int,
ispair bit
)

Как вставить данные логического типа

Для вставки данных типа bit вы можете использовать только значения 0, 1 и NULL. Например, ниже мы вставляем данные в ранее созданную таблицу myBooleanTable.

insert into myBooleanTable values 
(1,0),
(2,1),
(5,NULL)

Работа с запросами SQL

Следующий пример использует учебную базу данных Adventureworks. Если она у вас не установлена, обратитесь к этой статье относительно ее установки и конфигурирования.

В этом примере мы будем использовать таблицу HumanResource.Employee, которая содержит несколько столбцов типа данных bit. В первом примере мы используем битовый столбец SalariedFlag.

Следующий пример выводит столбцы BusinessEntityID, NationalIDNumber и SalariedFlag, когда SalariedFlag равен 1.

SELECT [BusinessEntityID] 
,[NationalIDNumber]
,[SalariedFlag]
FROM [HumanResources].[Employee]
WHERE SalariedFlag =1

Для получения аналогичной информации для сотрудников, у которых Salariedflag равен false, вы можете поменять значение флага SalariedFlag на false (0).

SELECT [BusinessEntityID] 
,[NationalIDNumber]
,[SalariedFlag]
FROM [HumanResources].[Employee]
WHERE SalariedFlag =0

И, наоборот, вы можете использовать значения TRUE и FALSE вместо 0 и 1, но это не рекомендуется.

SELECT [BusinessEntityID] 
,[NationalIDNumber]
,[SalariedFlag]
FROM [HumanResources].[Employee]
WHERE SalariedFlag ='true'

Наконец, мы можем использовать значение NULL в предложении WHERE. Использование NULL несколько отличается от использования значений 0 и 1, поскольку вы должны применять оператор IS вместо равенства.

Следующий пример иллюстрирует это.

SELECT [BusinessEntityID] 
,[NationalIDNumber]
,[SalariedFlag]
FROM [HumanResources].[Employee]
WHERE SalariedFlag IS NULL

Преобразование логических значений к другим типам данных

Следующий пример показывает результат сложения числового значения со значением типа bit. Мы объявляем переменную myBoolean, устанавливая ее значение в true, а затем прибавляем 2.

declare @myBoolean bit 
set @myBoolean='true'
select @myBoolean+2 result

Итак, в этом примере myBoolean равен 1, а 1+2 равно 3, это означает, что битовое значение неявно преобразуется к числовому.

Если мы попытаемся выполнить конкатенацию (оператор +), то получим ошибку. Следующий пример иллюстрирует эту проблему.

declare @myBoolean bit 
set @myBoolean='true'
select 'The value is'+@myBoolean

Сообщение об ошибке гласит:

Типы данных varchar и bit несовместимы в операции сложения.

Лучшим решением этой проблемы является использование оператора CONCAT, который преобразует переменную bit к строке.

declare @myBoolean bit 
set @myBoolean=1
select CONCAT ('The value is ',@myBoolean) as result

CONCAT конкатенирует строку с переменной bit, что даст следующий результат:

Как нерекомендуемый вариант, мы можем использовать функцию CONVERT для преобразования переменной bit в строку. Для данного сценария использование CONCAT является лучшим решением. Однако для других сценариев вы, возможно, не сможете использовать CONCAT, и потребуется использовать CONVERT вместо этого.

declare @myBoolean bit 
set @myBoolean='true'
select 'The value is'+CONVERT(varchar(1),@myBoolean) as result

Функция CONVERT преобразует тип данных bit переменной @myBoolean в varchar(1), которое уже может конкатенироваться со строкой.

Другим вариантом является использование CAST. CAST подобна CONVERT, мы включаем этот вариант только для того, что вы были знакомы с этим вариантом, который может вам встретиться где-то еще.

declare @myBoolean bit 
set @myBoolean='true'
select 'The value is'+CAST(@myBoolean as varchar(1)) as result

Синтаксис CAST несколько отличается от CONVERT. Вы должны указать выражение, а затем тип данных.

Хранимые процедуры с логическими переменными

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

В этом примере мы покажем, как создать хранимую процедуру с переменными типа bit и выполнить её.

Сначала создадим хранимую процедуру с именем salariedFlag, которая выводит LoginID пользователей с salariedFlag, равным true (1) или false (0). В соответствии с переменной @salariedFlag выводиться будут значения, указанные в предложении WHERE. Значения будут извлекаться из таблицы Employee.

create procedure salariedFlag 
(
@salariedFlag bit
)
as
select LoginID
from [HumanResources].[Employee]
where salariedFlag = @salariedFlag

Для выполнения хранимой процедуры используется предложение EXEC и указывается значение для переменной (параметра) @salariedFlag.

exec salariedFlag 1

Этот код выполняет salariedFlag, при этом @salaried получает значение 1 (TRUE).

Вот результат, возвращаемый хранимой процедурой:

Эти значения LoginID соответствуют SalariedFlag, равному TRUE. Если мы хотим увидеть LoginID, соответствующие значению FALSE (0), вы можете вызвать эту процедуру с другим значением параметра. Мы можем использовать EXECUTE вместо EXEC. Мы можем также включить в вызов имя параметра (что является лучшим вариантом использования, который легче понять и поддерживать, особенно в случае хранимых процедур с многими параметрами).

execute salariedFlag @salariedFlag='False'

Как видно в этом примере, мы используем команду EXECUTE, а не EXEC, и имя параметра @salariedFlag, в отличие от предыдущего примера. Наконец, мы используем значение, равное строке False, а не значению 0 (не рекомендуется, но работает).

Результат выполнения хранимой процедуры представлен ниже.

Типы данных SQL

Символьные типы данных — содержат буквы, цифры и специальные символы.

CHAR или CHAR(n) — символьные строки фиксированной длины. Длина строки определяется параметром n . CHAR без параметра соответсвует CHAR(1) . Для хранения таких данных всегда отводится n байт вне зависимости от реальной длины строки.

VARCHAR(n) — символьная строка переменной длины. Для хранения данных этого типа отводится число байт, соответствующее реальной длине строки.

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

INTEGER или INT — целое, для хранения которого отводится, как правило, 4 байта. (Замечание: число байт, отводимое для хранения того или иного числового типа данных зависит от используемой СУБД и аппаратной платформы, здесь приводятся наиболее «типичные» значения)
Интервал значений от — 2147483647 до + 2147483648
SMALLINT — короткое целое (2 байта), интервал значений от — 32767 до +32768

Вещественные типы данных — описывают числа с дробной частью.
FLOAT и SMALLFLOAT — числа с плавающей точкой (для хранения отводится обычно 8 и 4 байта соответсвенно).
DECIMAL(p) — тип данных аналогичный FLOAT с числом значащих цифр p .
DECIMAL(p,n) — аналогично предыдущему, p — общее количество десятичных цифр, n — количество цифр после десятичной запятой.

Денежные типы данных — описывают, естественно, денежные величины. Если в ваша система такого типа данных не поддерживает, то используйте DECIMAL(p,n) .

MONEY(p,n) — все аналогично типу DECIMAL(p,n) . Вводится только потому, что некоторые СУБД предусматривают для него специальные методы форматирования.

Дата и время — используются для хранения даты, времени и их комбинаций. Большинство СУБД умеет определять интервал между двумя датами, а также уменьшать или увеличивать дату на определенное количество времени.

DATE — тип данных для хранения даты.

TIME — тип данных для хранения времени.

INTERVAL — тип данных для хранения верменного интервала.

DATETIME — тип данных для хранения моментов времени (год + месяц + день + часы + минуты + секунды + доли секунд).

Двоичные типы данных — позволяют хранить данные любого объема в двоичном коде (оцифрованные изображения, исполняемые файлы и т.д.). Определения этих типов наиболее сильно различаются от системы к системе, часто используются ключевые слова:
BINARY
BYTE
BLOB

Последовательные типы данных — используются для представления возрастающих числовых последовательностей.
SERIAL — тип данных на основе INTEGER , позволяющий сформировать уникальное значение (например, для первичного ключа). При добавлении записи СУБД автоматически присваивает полю данного типа значение, получаемое из возрастающей последовательности целых чисел.

В заключение следует сказать, что для всех типов данных имеется общее значение NULL — «не определено». Это значение имеет каждый элемент столбца до тех пор, пока в него не будут введены данные. При создании таблицы можно явно указать СУБД могут ли элементы того или иного столбца иметь значения NULL (это не допустимо, например, для столбца, являющего первичным ключом).

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

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