Книги и статьи по SQL Rambler's Top100 Switch language to: English 14 июля 2020 г. 19:04:11


www.sql-ex.ru
Skip Navigation Links  

 

Print  Версия для печати

На главную страницу

О неявном преобразовании типов в SQL Server 2000

Моисеенко С.И.

Помимо типов данных в реляционной теории вводится фундаментальное понятие домена, как множества допустимых значений, которое может иметь атрибут. Можно сказать, что домен представляет собой пару {базовый тип данных, предикат}. При этом значение принадлежит домену только в том случае, если оно имеет соответствующий тип и предикат, вычисленный на этом значении, есть ИСТИНА. Атрибуты (столбцы таблицы) определяются на домене, т.е. помимо контроля типов СУБД при каждом изменении данных должна проверять также значение предиката. Изменение будет отклонено, если сохраняемое значение не удовлетворяет предикату домена.

Домен играет еще одну важную роль, а именно, сравниваться могут только значения, принадлежащие одному домену. Рассмотрим в качестве примера таблицу PC, а именно, столбцы speed (тактовая частота процессора) и hd (объем жесткого диска). Оба эти столбца имеют тип integer (или smallint). Однако это совершенно разные характеристики. Достаточно сказать, что в предметной области для них используются разные единицы измерения - герцы и байты. Так вот, если мы определим эти столбцы на разных доменах, то сравнение значения одного столбца со значением другого станет недопустимым. Причем контролироваться это будет СУБД. По аналогии с категорной и ссылочной целостностью такой контроль можно было бы назвать доменной целостностью, если бы этот термин не был занят в SQL Server под проверку ограничения CHECK, наложенного на столбцы таблицы. А так определенная "доменная целостность" никак не ограничивает сравнения.

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

  • избавляет приложения от необходимости встраивать (и дублировать!) в них необходимые проверки;
  • гарантирует более высокий уровень безопасности. Ограничения, встроенные в приложения, легко обойти. Достаточно обратиться к базе данных, минуя приложение.
  • облегчает сопровождение и разработку. Если ограничения предметной области изменятся, то соответствующие программные изменения нужно будет сделать в одном месте, а не во всех приложениях, работающих с базой данных.

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

В цепочке "Теория - Стандарт - Реализация" последовательно теряется строгость реляционной теории, в результате чего мы не можем вполне прозрачно взаимодействовать с реляционными СУБД разных производителей.
Здесь же я хочу показать небольшой пример того, как следует обращаться с типами в SQL Server.

Итак, реально мы имеем то, что сравниваться могут значения одного типа. Для преобразования типов стандарт предлагает функцию CAST. Т.е. в общем случае мы должны преобразовать сравниваемые значения к одному типу, а затем уже выполнять операцию сравнения (или присвоения). Что же произойдет, если мы переменной (или столбцу) одного типа просто присвоим значение другого типа? Рассмотрим простой пример кода на T-SQL:

DECLARE @vc VARCHAR(10), @mn MONEY, @ft FLOAT

SELECT @vc = '499.99'
PRINT @vc
SELECT @ft = @vc
PRINT @ft

Здесь мы описывает три переменные соответственно строкового типа (VARCHAR), денежного типа (MONEY) и числа с плавающей точкой (FLOAT). Далее строковой переменной присваиваем константу соответствующего типа, а затем присваиваем переменной типа FLOAT значение строковой переменной. В результате получаем два одинаковых результата - 499.99 (оператор PRINT осуществляет вывод на консоль). То, что произошло, называется неявным преобразованием типов, т.е. строковое значение - '499.99' было автоматически приведено к типу FLOAT и присвоено переменной @ft.

Добавим в конец кода еще пару строк:

SELECT @mn = @vc
PRINT @mn

В результате получим два похожих сообщения об ошибке:

Implicit conversion from data type varchar to money is not allowed. Use the CONVERT function to run this query.

и

Implicit conversion from data type money to nvarchar is not allowed. Use the CONVERT function to run this query.

в одном из которых говорится о том, что неявное преобразование к типу money не допускается, а в другом - о недопустимости и обратного (к varchar) преобразования. Как и следовало ожидать, нам предлагается использовать явное преобразование с помощи функции COVERT. Однако чтобы быть ближе к стандарту, воспользуемся функцией CAST:

SELECT @mn=CAST(@vc AS MONEY) PRINT @mn

От первого сообщения об ошибке мы избавились. Напрашивается вывод о том, что второе сообщение дает оператор PRINT. Инстинкты подсказывают заглянуть в справку. В BOL об операторе PRINT говорится, что переменная, которая может использоваться в этом операторе, должна быть любого допустимого строкового типа ( char или varchar) или же должна неявно приводиться к этому типу.

Перепишем последнюю строку так

PRINT CAST(@mn AS VARCHAR)

Все работает. Главный вывод, который мы отсюда извлекаем, заключается в том, что не все типы (даже если мы не видим особых причин тому) допускают неявное преобразование.

В частности, не выполняется неявное приведение типа MONEY к типам CHAR, VARCHAR, NCHAR, NVARCHAR и наоборот.

К сожалению, приведенные здесь примеры нельзя выполнить непосредственно на сайте. Это обусловлено тем, что пока мы не реализовали возможность исполнения наборов операторов (пакетов).
Поэтому тем, кто захочет проверить справедливость сказанного, придется воспользоваться Query Analyzer.

На главную страницу

Print  Версия для печати


Использование любых материалов данного сайта возможно только
при условии обязательного размещения прямой ссылки на сайт
http://www.sqlbooks.ru
на каждой странице, где размещены используемые материалы.

 Начало   Статьи    Книги 
Рейтинг@Mail.ru Rambler's Top100 Alt Упражнения по SQL: обучение, тестирование, сертификация по языку SQL Copyright c 2002-2006. All rights reserved.