Sql как присвоить значение null
Поля и переменные могут быть установлены в NULL с помощью того же синтаксиса, что и для обычных значений:
insert into MyTable values (1, 'teststring', NULL, '8-May-2004')
update MyTable set MyField = null where YourField = -1
if (Number = 0) then MyVariable = null;
— « Минуточку. но вы сказали, что MyField = NULL было недопустимо! »
Это верно. для оператора сравнения « = » (по крайней мере для СУБД Firebird до версии 2.0). Но здесь мы говорим о знаке « = », как об операторе присваивания . К сожалению, в SQL оба эти оператора имеют один и тот же символ. В случае присваивания, которое выполняется с помощью « = » или внутри списка вставки, вы можете трактовать NULL , как любое другое значение, — специальный синтаксис не требуется.
| Firebird Documentation Index → NULL в СУБД Firebird → Установка значения поля или переменной в NULL |
Обработка значений 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
Дальнейшие действия
Обработка значений NULL
Значение NULL в реляционной базе данных используется, если значение в столбце неизвестно или отсутствует. NULL не является ни пустой строкой (для типов данных character или datetime), ни нулевым значением (для числовых типов данных). В спецификации ANSI SQL-92 указано, что значение NULL должно быть одинаковым для всех типов данных, чтобы все значения NULL обрабатывались согласованно. Пространство имен System.Data.SqlTypes обеспечивает семантику со значением NULL, реализуя интерфейс INullable. Каждый из типов данных в System.Data.SqlTypes имеет собственное свойство IsNull и значение Null , которое может быть назначено экземпляру этого типа данных.
В платформа .NET Framework версии 2.0 появилась поддержка типов значений, допускающих значение NULL, которые позволяют программистам расширять тип значения для представления всех значений базового типа. Эти типы значений CLR, допускающих значение NULL, представляют экземпляр Nullable структуры . Эта возможность особенно полезна, если типы значений упакованы и распакованы, что обеспечивает улучшенную совместимость с типами объектов. Типы значений, допускающих значение NULL в среде CLR, не предназначены для хранения значений NULL базы данных, так как ANSI SQL не ведет себя так же, как null ссылка (или Nothing в Visual Basic). Для работы со значениями NULL в базе данных ANSI SQL используйте значения NULL System.Data.SqlTypes вместо Nullable. Дополнительные сведения о работе с типами значений CLR, допускающих значение NULL, в Visual Basic см. в разделе Типы значений, допускающих значение NULL, а для C# — в разделе Типы значений, допускающих значение 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 .
Значение по умолчанию для любого экземпляра System.Data.SqlTypes— NULL.
Значения NULL в System.Data.SqlTypes относятся к определенному типу и не могут быть представлены одним значением, таким как DbNull . Чтобы проверить на наличие значений NULL, используйте свойство IsNull .
Значения NULL могут быть назначены DataColumn, как показано в следующем примере кода. Вы можете напрямую назначить значения NULL для переменных SqlTypes без запуска исключения.
Пример
В следующем примере кода показано создание DataTable с двумя столбцами, определенными как SqlInt32 и SqlString. Код добавляет одну строку известных значений, одну строку значений NULL, а затем выполняет итерацию по DataTable, присваивая значения переменным и отображая выходные данные в окне консоли.
static void WorkWithSqlNulls() < DataTable table = new(); // 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(); >
Private Sub WorkWithSqlNulls() Dim table As New DataTable() ' Specify the SqlType for each column. Dim idColumn As DataColumn = _ table.Columns.Add("ID", GetType(SqlInt32)) Dim descColumn As DataColumn = _ table.Columns.Add("Description", GetType(SqlString)) ' Add some data. Dim row As DataRow = table.NewRow() row("ID") = 123 row("Description") = "Side Mirror" table.Rows.Add(row) ' Add null values. row = table.NewRow() row("ID") = SqlInt32.Null row("Description") = SqlString.Null table.Rows.Add(row) ' Initialize variables to use when ' extracting the data. Dim isColumnNull As SqlBoolean = False Dim idValue As SqlInt32 = SqlInt32.Zero Dim descriptionValue As SqlString = SqlString.Null ' Iterate through the DataTable and display the values. For Each row In table.Rows ' Assign values to variables. Note that you ' do not have to test for null values. idValue = CType(row("ID"), SqlInt32) descriptionValue = CType(row("Description"), SqlString) ' Test for null value with ID column isColumnNull = idValue.IsNull ' Display variable values in console window. Console.Write("isColumnNull=, Description=", _ isColumnNull, idValue, descriptionValue) Console.WriteLine() Next row End Sub
В этом примере отображаются следующие результаты:
isColumnNull=False, Description=Side Mirror isColumnNull=True, Description=Null
Присвоение для многих столбцов или строк
DataTable.Add , DataTable.LoadDataRow или другие API-интерфейсы, принимающие массив ItemArray, который сопоставляется со строкой, сопоставляют значение NULL со значением по умолчанию DataColumn. Если объект в массиве содержит DbNull.Value или строго типизированный аналог, применяются те же правила, которые описаны выше.
Кроме того, следующие правила применяются к экземпляру назначений NULL DataRow.[«columnName»] :
- Значение по умолчанию — DbNull.Value для всех, кроме строго типизированных столбцов NULL, где это соответствующее строго типизированное значение 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 с типами SqlType и 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, а затем пара пустых строк.
static void CompareNulls() < // Create two new null strings. SqlString a = new(); SqlString b = new(); // 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)); > static string SqlStringEquals(SqlString string1, SqlString string2) < // SqlString.Equals uses database semantics for evaluating nulls. var returnValue = SqlString.Equals(string1, string2).ToString(); return returnValue; >static string StringEquals(SqlString string1, SqlString string2) < // String.Equals uses CLR type semantics for evaluating nulls. var returnValue = string1.Equals(string2).ToString(); return returnValue; >>
Private Sub CompareNulls() ' Create two new null strings. Dim a As New SqlString Dim b As 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)) End Sub Private Function SqlStringEquals(ByVal string1 As SqlString, _ ByVal string2 As SqlString) As String ' SqlString.Equals uses database semantics for evaluating nulls. Dim returnValue As String = SqlString.Equals(string1, string2).ToString() Return returnValue End Function Private Function StringEquals(ByVal string1 As SqlString, _ ByVal string2 As SqlString) As String ' String.Equals uses CLR type semantics for evaluating nulls. Dim returnValue As String = string1.Equals(string2).ToString() Return returnValue End Function
Получается следующий вывод:
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
См. также
- Типы данных SQL Server и ADO.NET
- Общие сведения об ADO.NET
Значение NULL в SQL – неизвестное значение
Примечание:
Во всех статьях текущей категории уроков по SQL используются примеры и задачи, основанные на учебной базе данных.
Приступая к изучению данного материала, рекомендуется ознакомиться с описанием учебной БД.
Даже для небольших баз данных часто встречаются ситуации, когда значение какого-либо поля таблицы может быть неизвестно. Причины возникновения подобных ситуаций могут быть разными, начиная ошибками ПО и проектирования БД, заканчивая особенностями бизнес-процессов организации.
Если рассмотреть диаграмму таблицы сотрудников учебной БД, то можно заметить, что последний столбец диаграммы указывает возможность наличия неизвестных значение в конкретном поле, а именно:

- Отчество. Вполне возможно, что сотрудником является гражданин страны, где не используется отчество.
- Дата увольнения может отсутствовать, так как увольнения еще не было.
- Группа может быть неизвестна, потому что сотрудник может быть не распределен в группу на каком-то из этапов приема на работу.
Важно понять, что неизвестные (отсутствующие) значения – это не ноль (для числовых полей) и не пустая строка (для текстовых полей). Так как ноль является вполне конкретным значением, например, 0 рублей задолженности, а пустая строка сообщает о том, что на данный момент ничего кроме строки нулевой длины в поле строки быть не должно. В примере с отчеством, приведенном выше, вместо значения NULL можно задать пустую строку и это внесло бы дополнительную ясность, что отчество сотрудника нет в принципе, а не то, что его забыли внести.
Поиск отсутствующих значений
Выше было определено, что NULL не является конкретным значением, поэтому нужно понять, как операторы сравнения с ним будут работать. Никакое значение не может быть равно (также быть больше или меньше) неизвестному значению, даже условие NULL = NULL является ложным. Чтобы определить отсутствующее значения используется специальное условие IS NULL (является неизвестным). И наоборот, если требуется найти известные значения, то задается условие IS NOT NULL.
Рассмотрим задачу.
Найти всех сотрудников, которые были когда-либо уволены.
Решение.
Если в поле «Дата_увольнения» таблицы сотрудников отсутствует значение, то сотрудники работают на данный момент. Следовательно, нужно найти строки, где значение известно. Следующий sql-запрос выведет 7 строк, удовлетворяющих решению:
USE CallCenter SELECT * FROM Сотрудники WHERE Дата_увольнения IS NOT NULL
Решим еще одну задачу.
Вывести непринятые звонки за 1 декабря 2014 года.
Решение.
Звонок считается непринятым, если в таблице «Звонки» в поле «Сотрудник» отсутствует id принявшего звонок оператора. Отфильтровав таблицу по полям «Сотрудник» и «Дата_Время», получим 184 строки, удовлетворяющих запросу:
USE CallCenter SELECT * FROM Звонки WHERE Сотрудник IS NULL AND Дата_Время >= '01/12/2014 00:00:00' AND Дата_Время < '02/12/2014 00:00:00'
Обработка неизвестных значений
Если в своих запросах, Вы будете использовать поля, которые допускают значения NULL, то обязательно обрабатывайте такие поля, чтобы избежать ошибок. Например, любые арифметические операции или объединения строк, где в качестве аргумента будет хотя бы одно значение NULL, вернут неизвестное значение.
Рассмотрим пример.
Необходимо определить стаж работы каждого сотрудника, включая уволенных, на текущий момент. Стаж вывести в днях.
Для определения стажа необходимо найти интервал (разницу) между датой найма сотрудника и датой увольнения. Для этого можно использовать функцию DATEDIFF (ее описание можно найти в документации Microsoft). Но как быть с не уволенными сотрудниками, у которых отсутствует значение даты увольнения? Если выполнить ниже приведенный запрос, то можно убедиться, что большинство строк не покажут стаж:
USE CallCenter SELECT id, DATEDIFF(DAY, Дата_найма, Дата_увольнения) AS Стаж FROM Сотрудники
Поэтому обработаем поле «Дата_увольнения», применив функции ISNULL (если первый аргумент является NULL, то функция возвращает второй аргумент) и GETDATE (возвращает текущую системную дату и время). Следующий запрос выведет стаж в каждой строке:
USE CallCenter SELECT id, DATEDIFF(DAY, Дата_найма, ISNULL(Дата_увольнения, GETDATE())) AS Стаж FROM Сотрудники
- Объединение таблиц – UNION
- Соединение таблиц – операция JOIN и ее виды
- Тест на знание основ SQL
Если материалы office-menu.ru Вам помогли, то поддержите, пожалуйста, проект, чтобы я мог развивать его дальше.