Скалярные типы данных
Каждая константа, переменная и параметр имеют тип данных (или тип), который определяет формат хранения, ограничения и допустимый диапазон значений. PL/SQL предоставляет множество предопределенных типов данных.
Скалярный тип данных (scalar data type) содержит одно значение и не имеет внутренних компонентов. Скалярные типы данных делятся на четыре категории:
- Числовые
- Символьные
- Даты
- Логические данные.
Символьный и числовой типы данных имеют подтипы, которые налагают определенные ограничения на базовый тип. Например, INTEGER (“целое число”) и POSITIVE (“положительное число”) являются подтипами базового типа NUMBER.
Базы данных. Вводный курс
Лекция 17. Общая характеристика оператора SELECT и организация списка ссылок на таблицы в разделе FROM
17.1. Введение
В этой и следующих трех лекциях рассматривается важнейший оператор языка SQL – оператор SELECT , предназначенный для выборки данных из SQL-ориентированной базы данных. Этот оператор имеет довольно сложную и развитую структуру, но, по нашему мнению, его необходимо знать любому специалисту, так или иначе связанному с использованием баз данных; поэтому в нашем курсе ему уделяется так много внимания. Первая лекция носит подготовительный характер. В ней мы рассматриваем виды скалярных выражений, используемые, прежде всего, в конструкциях оператора SELECT , обсуждаем базовую семантику выполнения этого оператора и анализируем принципы и разновидности указания таблиц, из которых производится выборка данных.
Несмотря на то, что язык SQL является полным языком баз данных, включающим множество разнообразных средств определения схемы, ограничения и поддержки целостности базы данных, поддержки администрирования, заполнения и модификации таблиц базы данных, поддержки разработки приложений и т. д., для подавляющего большинства пользователей этот язык остается языком запросов, т. е. языком, позволяющим формулировать произвольно сложные и точные декларативные запросы к базе данных.
Как отмечалось в конце предыдущей лекции, структура стандарта языка SQL фактически не позволяет описать одну часть языка (в частности, средства запросов) в отрыве от других частей. Тем не менее, полагая, что средства выборки данных составляют наиболее интересную и практически значимую часть языка, мы выделили для их рассмотрения несколько отдельных лекций.
Напомним, что в этом курсе мы ограничиваемся базовым подмножеством SQL:1999 и SQL:2003 («прямым SQL») и даже это подмножество описываем не в полном объеме стандарта. Кроме того, в данной лекции мы не будем точно придерживаться порядка введения понятий и синтаксических конструкций, принятого в стандарте языка. Мы начнем с некоторой общей картины, дающей представление об операторе выборки, а затем будем постепенно уточнять ее.
17.2. Скалярные выражения
Скалярное выражение 115) – это выражение, вырабатывающее результат некоторого типа, специфицированного в стандарте. Скалярные выражения являются основой языка SQL, поскольку, хотя это реляционный язык, все условия, элементы списков выборки и т. д. базируются именно на скалярных выражениях. В SQL:1999 имеется несколько разновидностей скалярных выражений. К числу наиболее важных разновидностей относятся численные выражения; выражения со значениями-строками символов; выражения со значениями даты-времени; выражения со значениями-временными интервалами; булевские выражения. Мы не будем слишком глубоко вникать в тонкости, но тем не менее приведем некоторые базовые спецификации и пояснения.
Прежде чем перейти к конкретным видам скалярных выражений, рассмотрим некоторые наиболее общие языковые конструкции, на которых эти выражения базируются.
17.2.1. Общие синтаксические правила построения скалярных выражений
В SQL:2003 имеются девять разновидностей выражений в соответствии с девятью категориями типов данных, значения которых вырабатываются при вычислении выражения
Как уже отмечалось в начале этого раздела, мы ограничимся обсуждением первых пяти разновидностей выражений. В основе построения этих видов выражений лежит первичное выражение, определяемое следующим синтаксическим правилом:
В пределах этого курса можно считать, что спецификация беззнакового значения ( unsigned_value_specification ) – это всегда литерал соответствующего типа или вызов ниладической функции (например, CURRENT_USER ) 116) . При вычислении выражения V для строки таблицы каждая ссылка на столбец ( column_reference ) этой таблицы, непосредственно содержащаяся в V , рассматривается как ссылка на значение данного столбца в данной строке. Агрегатные функции (функции над множествами – set_function_specification ) обсуждаются в лекции 19. Если первичное выражение является скалярным подзапросом ( scalar_subquery , или подзапросом, результатом которого является таблица, состоящая из одной строки и одного столбца) и результат подзапроса пуст, то результат первичного выражения – неопределенное значение. (Подзапросы обсуждаются в следующей лекции, выражения с переключателем ( case_expression ) рассматриваются ниже в этом разделе.)
17.2.2. Численные выражения
Численное выражение – это выражение, значение которого относится к числовому типу данных. Вот формальный синтаксис численного выражения:
Следует обратить внимание на то, что в численных выражениях SQL первичная составляющая ( numeric_primary ) является либо первичным выражением (см. выше), либо вызовом функции с численным значением ( numeric_value_function ). Из этого, в частности, следует, что в численные выражения могут входить выражения с переключателем и операции преобразования типов. Вызовы функций с численным значением определяются следующими синтаксическими правилами:
Мы достаточно подробно обсуждали функции определения позиции и длины по отношению к символьным и битовым строкам при рассмотрении соответствующих типов данных; здесь приводится только уточненный синтаксис их вызова. Функция EXTRACT извлечения поля из значений дата-время или интервал позволяет получить в виде точного числа с масштабом 0 значение любого поля (года, месяца, дня и т. д.). Какой конкретный тип точных чисел будет выбран – определяется в реализации. Функции ABS и MOD возвращают абсолютное значение числа и остаток от деления одного целого значения на другое соответственно.
17.2.3. Выражения, значениями которых являются символьные или битовые строки
Выражения символьных и битовых строк – это выражения, значениями которых являются символьные или битовые строки. Соответствующие конструкции определяются следующим синтаксисом:
Если не вдаваться в тонкости, смысл выражений символьных и битовых строк понятен из описания синтаксиса: единственная применимая для построения выражений операция – это конкатенация, производящая «склейку» строк-операндов. Более важно то, что первичной составляющей выражения над строками может быть как первичное скалярное выражение (см. выше), так и вызов функций, возвращающих строчные значения. Репертуар и синтаксис вызова таких функций определяются следующими правилами:
Основные полезные функции – выделение подстроки ( SUBSTRING ) и замена малых букв на заглавные и наоборот ( UPPER и LOWER ) – мы упоминали при рассмотрении типов символьных и битовых строк. Обсуждение функции SUBSTRING . SIMILAR . ESCAPE отложим до следующей лекции. Как видно из описания синтаксиса функций, возвращающих строчные значения, для символьных строк имеются еще четыре функции: CONVERT , TRANSLATE , TRIM и OVERLAY . По смыслу все они очень просты. Функция CONVERT меняет кодировку символов в заданной строке, причем набор символов не меняется. Способ задания правил перекодировки определяется в реализации. Функция TRANSLATE , наоборот, в соответствии с правилами трансляции «переводит» текстовую строку на другой язык (используя набор символов целевого алфавита). Кодировка не меняется. Функция TRIM «отсекает» последовательности указанного символа в начале, в конце или в конце и начале заданной строки. Наконец, функция OVERLAY заменяет указанную подстроку первого операнда строкой, заданной в качестве второго операнда.
17.2.4. Выражения даты-времени
К выражениям даты-времени мы относим выражения, вырабатывающие значения типа дата-время и интервал. Выражения даты-времени определяются следующими синтаксическими правилами:
Как видно из описания синтаксиса, сами выражения строятся очень просто – на основе обычных арифметических операций. Снова более интересны первичные составляющие – вызовы функций, возвращающих значение дата-время. Эти вызовы определяются следующим синтаксисом:
Видимо, приведенные синтаксические правила не нуждаются в комментариях: можно получить текущую дату, а также текущее время с желаемой точностью. Отличие функций LOCALTIME и LOCALTIMESTAMP от CURRENT_TIME и CURRENT_TIMESTAMP , соответственно, состоит в том, что первая пара функций не возвращает смещение локального времени от Гринвича.
Синтаксис выражений со значениями типа интервал определяется следующими правилами:
Как видно из приведенных правил, выражения со значениями типа интервал устроены очень просто; почти вся содержательная информация была приведена при обсуждении соответствующего типа данных. Стоит только заметить, что квалификатор интервала указывается для того, чтобы явно специфицировать единицу измерения интервала. Поддерживается только одна функция ABS (абсолютное значение), аргументом которой является выражение со значением типа интервал.
17.2.5. Булевские выражения
К булевским выражениям относятся выражения, вырабатывающие значения булевского типа (напомним, что булевский тип языка SQL содержит три логических значения – true , false и unknown ). Булевские выражения определяются следующими синтаксическими правилами:
Выражения вычисляются слева направо с учетом приоритетов операций (наиболее высокий приоритет имеет унарная операция NOT , следующим уровнем приоритета обладает «мультипликативная» операция конъюнкции AND , и самый низкий приоритет у «аддитивной» операции дизъюнкции OR ) и круглых скобок. Операции IS и IS NOT определяются следующими таблицами истинности:
| IS | TRUE | FALSE | UNKNOWN |
|---|---|---|---|
| TRUE | TRUE | FALSE | FALSE |
| FALSE | FALSE | TRUE | FALSE |
| UNKNOWN | FALSE | FALSE | TRUE |
| IS NOT | TRUE | FALSE | UNKNOWN |
|---|---|---|---|
| TRUE | FALSE | TRUE | TRUE |
| FALSE | TRUE | FALSE | TRUE |
| UNKNOWN | TRUE | TRUE | FALSE |
17.2.6. Выражения с переключателем
Выражения с переключателем в некотором смысле ортогональны рассмотренным выше видам выражений, поскольку разные выражения с переключателем могут вырабатывать значения разных типов в зависимости от типа данных элементов. Поскольку мы еще вообще не рассматривали этот вид выражений, обсудим их более подробно. Как обычно, начнем с синтаксиса:
Наиболее общим видом выражения с переключателем является выражение с поисковым переключателем ( searched_case ). Правила вычисления выражений этого вида состоят в следующем. Вычисляется логическое выражение, указанное в первом разделе WHEN списка ( searched_when_clause_list ). Если значение этого логического выражения равняется true, то значением всего выражения с поисковым переключателем является значение выражения, указанного в первом разделе WHEN после ключевого слова THEN . Иначе аналогичные действия производятся для второго раздела WHEN и т. д. Если ни для одного раздела WHEN при вычислении логического выражения не было получено значение true, то значением всего выражения с поисковым переключателем является значение выражения, указанного в разделе ELSE . Типы всех выражений, значения которых могут являться результатом выражения с поисковым переключателем, должны быть совместимыми, и типом результата является «наименьший общий» тип набора типов выражений-кандидатов на выработку результата 117) . Если в выражении отсутствует раздел ELSE , предполагается наличие раздела ELSE NULL .
В выражении с простым переключателем ( simple_case ) тип данных операнда переключателя (выражения, непосредственно следующего за ключевым словом CASE , назовем его CO – Case Operand ) должен быть совместим с типом данных операнда каждого варианта (выражения, непосредственно следующего за ключевым словом WHEN ; назовем WO – When Operand ). Выражение с простым переключателем
эквивалентно выражению с поисковым переключателем
Выражение NULLIF (V1, V2) эквивалентно следующему выражению с переключателем:
Выражение COALESCE (V1, V2) эквивалентно следующему выражению с переключателем:
Выражение COALESCE (V1, V2, . . . Vn) для n 3 эквивалентно следующему выражению с переключателем:
115 В стандарте языка SQL в качестве общего термина для обозначения таких выражений используется термин value expression . Однако в менее формальных публикациях обычно применяется более понятный термин scalar expression , для которого, вдобавок, существует адекватный русский эквивалент скалярное выражение. В этом курсе мы также предпочитаем использовать именно этот термин.
116 Другие варианты появляются во встраиваемом и динамическом SQL, а также расширении языка, предназначенного для написания кода хранимых процедур, триггеров, методов определяемых пользователями типов и т.д. В любом случае беззнаковое значение известно до начала компиляции любой содержащей его конструкции языка SQL.
117 Для набора типов T1 , T2 , …, Tn , будем называть тип T , если значения каждого из типов T1 , T2 , …, Tn неявно приводимы к типу T , и не существует типа T’ , такого, что значения типов T1 , T2 , …, Tn неявно приводимы к типу T’ , и значения типа T’ неявно приводимы к типу T .
3.3. Хранимые функции Transact-SQL
С SQL Server вы можете создавать ваши собственные функции, добавляющие и расширяющие функции, предоставляемые системой. Функции могут получать 0 или более параметров и возвращать скалярное значение или таблицу. Входные параметры могут быть любого типа, исключая timestamp, cursor, table.
Сервер SQL поддерживает три типа функций определенных пользователем:
- Скалярные функции – похожи на встроенные функции;
- Функция, возвращающая таблицу — возвращает результат единичного оператора SELECT. Он похож на объект просмотра, но имеет большую эластичность благодаря использованию параметров, и расширяет возможности индексированного объекта просмотра;
- Многооператорная функция — возвращает таблицу созданную одним или несколькими операторами Transact-SQL, чем напоминает хранимые процедуры. В отличие от процедур, на такие функции можно ссылаться в WHERE как на объект просмотра.
3.3.1. Создание хранимой функции
Создание функций очень похоже на создание процедур и объектов просмотра. Недаром мы рассматриваем все эти темы в одной главе. Для создания функции используется оператор CREATE FUNCTION. В зависимости от типа, Объявление будет отличаться. Рассмотрим все три типа объявления.
Функция, возвращающая таблицу:
3.3.2. Скалярные функции в Transact-SQL
Давайте для примера создадим функцию, которая будет возвращать скалярное значение. Например, результат перемножение цены на количество указанного товара. Товар будет идентифицироваться по названию и дате, ведь мы договорились, что сочетание этих полей дает уникальность. Но будьте осторожны, при тестировании запроса, если в разделе 3.2.8 вы выполнили запрос на изменение данных и создали дубликаты покупок за 1.1.2005-го года.
Итак, посмотрим сначала на код создание скалярной функции:
После оператора CREATE FUNCTION мы указываем имя функции. Далее, в скобках идут параметры, которые необходимо передать. Да, параметры должны передаваться через запятую в круглых скобках. В этом объявление отличается от процедур и эту разницу необходимо помнить.
Далее указывается ключевое слово RETURNS, за которым идет описание типа возвращаемого значения. Для скалярной функции это могут быть любые типы (строки, числа, даты и т.д.).
Код, который должна выполнять функция пишется между ключевыми словами BEGIN (начало) и END (конец). В коде можно использовать любые операторы Transact-SQL, которые мы изучали ранее. Итак, объявление нашей функции в упрощенном виде можно описать следующим образом:
Между ключевыми словами BEGIN и END у нас выполняется следующий код:
В первой строке объявляется переменная @Summ. Она нужна для хранения промежуточного результата расчетов. Далее выполняется запрос SELECT, в котором происходит поиск строки по дате и названию товара в таблице товаров. В найденной строке перемножаются поля цены и количества, и результат записывается в переменную @Summ.
Обратите внимание, что в конце запроса стоит знак точки с запятой. Каждый запрос должен заканчиваться этим символом, но в большинстве примеров мы этим пренебрегали, но в функции отсутствие символа «;» может привести к ошибке.
В последней строке возвращаем результат. Для этого нужно написать ключевое слово RETURN, после которого пишется возвращаемое значение или переменная. В данном случае, возвращаться будет содержимое переменной @Summ.
Так как функция скалярная, то и возвращаемое значение должно быть скалярным и при этом соответствовать типу, описанному после ключевого слова RETURNS.
3.3.3. Использование функций
Как выполнить такую функцию? Да также, как и многие другие системные функции (например, GETDATE()). Например, следующий пример использует функцию в операторе SELECT:
В этом примере, оператор SELECT возвращает результат выполнения функции GetSumm. Функция принадлежит пользователю dbo, поэтому перед именем я указал владельца. После имени в скобках должны быть перечислены параметры в том же порядке, что и при объявлении функции. В данном примере я запрашиваю затраты на картофель, купленный 3.3.2005.
Выполните следующий запрос и убедитесь, что он вернул тот же результат, что и созданная нами функция:
Функции можно использовать не только в операторе SELECT, но и напрямую, присваивая значение переменной. Например:
В этом примере мы объявили переменную @Summ типа numeric(10,2). Именно такой тип возвращает функция. В следующей строке переменной присваивается результат выполнения Summ, с помощью SET.
Давайте посмотрим, что произойдет, если передать функции такие параметры, при которых запрос функции вернет более одной строки. В нашей таблице товаров сочетание даты и название не дает уникальности, потому что мы ее нарушили. Первичного ключа в таблице также нет, и среди товаров у меня есть четыре строки, которые имеют свои точные копии. Это нарушает правило уникальности строк в реляционных базах, но очень наглядно показывает, что в реальной жизни нарушать его нельзя.
Итак, в моей таблице есть две покупки хлеба 1.1.2005-го числа. Попробую запросить у функцию сумму:
Результатом будет только одно число, хотя строки две. А какую строку из двух вернул сервер? Никто точно сказать не может, потому что они обе одинаковые и без единого различия. Поэтому сервер скорей всего вернул первую из строк.
3.3.4. Функция, возвращающая таблицу
В следующем примере мы создаем функцию, которая будет возвращать в качестве результата таблицу. В качестве примера, создадим функцию, которая будет возвращать таблицу товаров, и для каждой строки рассчитаем произведение колонок количества и цены:
Начало функции такое же, как у скалярной – указываем оператор CREATE FUNCTION и имя функции. Я специально создал эту функцию без параметров, чтобы вы увидели, как это делается. Не смотря на то, что параметров нет, после имени должны идти круглые скобки, в которых не надо ничего писать. Если не указать скобок, то сервер вернет ошибку и функция не будет создана.
Разница есть и в секции RETURNS, после которой указывается тип TABLE, что говорит о необходимости вернуть таблицу. После этого идет ключевое слово AS и RETURN, после которого должно идти возвращаемое значение. Для функции данного типа в секции RETURN нужно в скобках указать запрос, результат которого и будет возвращаться функцией.
Когда пишете запрос, то все его поля должны содержать имена. Если одно из полей не имеет имени, то результатом выполнения оператора CREATE FUNCTION будет ошибка. В нашем примере последнее поле является результатом перемножения полей «Цена» и «Количество», а такие поля не имеют имени, поэтому мы его задаем с помощью ключевого слова AS.
Посмотрим, как можно использовать такую функцию с помощью оператора SELECT:
Так как мы используем простой оператор SELECT, то мы можем и ограничивать вывод определенными строками, с помощью ограничений в секции WHERE. Например, в следующем примере выбираем из результата функции только те строки, в которых поле «Количество» содержит значение 1:
Функция возвращает в качестве результата таблице, которую вы можете использовать как любую другую таблицу базы данных. Давайте создадим пример в котором можно будет увидеть использование функции в связи с таблицами. Для начала создадим функцию, которая будет возвращать идентификатор работников таблицы tbPeoples и объединенные в одно поле ФИО:
Функция возвращает нам идентификатор строки, с помощью которого мы легко можем связать результат с таблицей телефонов. Попробуем сделать это с помощью простого SQL запроса:
Как видите, функции, возвращающие таблицы очень удобны. Они больше, чем процедуры похожи на объекты просмотра, но при этом позволяют принимать параметры. Таким образом, можно сделать так, чтобы сама функция возвращала нам только то, что нужно. Вьюшки такого не могут делать по определению. Чтобы получить нужные данные, вьюшка должна выполнить свой SELECT запрос, а потом уже во внешнем запросе мы пишем еще один оператор SELECT, с помощью которого ограничивается вывод до необходимого. Таким образом, выполняется два запроса SELECT, что для большой таблицы достаточно накладно. Функция же может сразу вернуть только то, что нужно.
Рассмотрим пример, функция GetPeoples у нас возвращает все строки таблицы. Чтобы получить только нужную фамилию, нужно писать запрос типа:
В этом случае будут выполняться два запроса: этот и еще один внутри функции. Но если передавать фамилию в качестве параметра в функцию и там сделать секцию WHERE, то можно обойтись и одним запросом SELECT:
3.3.5. Много операторная функция возвращающая таблицу
Все функции, созданные в разделе 3.3.5 могут возвращать таблицу, сгенерированную только одним оператором SQL. А как же тогда сделать возможность выполнять несколько операций? Например, вы можете захотеть выполнять дополнительные проверки входных параметров для обеспечения безопасности. Проверки лишними не бывает, особенно входных данных и особенно, если эти входные данные указываются пользователем.
Следующий пример показывает, как создать функцию, которая может вернуть в качестве результата таблицу, и при этом, в теле функции могут выполняться несколько операторов:
Это упрощенный вид создания процедуры. Более полный вид мы рассматривали в начале главы, а сейчас я упростил объявление, чтобы проще было его разбирать.
Объявление больше похоже на создание скалярных функций. Первая строка без изменений. В секции RETURNS объявляется переменная, которая имеет тип TABLE. После этого, в скобках нужно описать поля результирующей таблицы. После ключевого слова AS идtт пара операторов BEGIN и END, между которыми может выполняться какое угодно количество операций. Выполнение операций заканчивается ключевым словом RETURN.
Вот тут есть одно отличие от скалярных функций – после RETURN мы указывали имя переменной, значение которой должно стать результатом. В данном случае ничего указывать не надо. Мы уже объявили переменную в секции RETURNS и описали формат этой переменной. В теле функции мы можем и должны наполнить эту переменную значениями и именно это попадет в результат.
Теперь посмотрим на пример создания функции:
В данном примере в качестве результата объявлена переменная @ret, которая является таблицей из двух полей «idPeoples» типа int и «vcFIO» типа varchar длинной в 50 символов. В теле функции в эту таблицу записываются значения из таблицы tbPeoples и выполняется оператор RETURN, завершающий выполнение функции.
В использовании, такая функция ничем не отличается от рассмотренных ранее. Например, следующий запрос выбирает все данные, которые возвращает функция:
3.3.6. Опции функций
При создании функций могут использоваться следующие опции SCHEMABINDING (привязать к схеме) и/или ENCRYPTION (шифровать текст функции). Если вторая опция нам уже известна по вьюшкам и процедурам (позволяет шифровать исходный код функции в системных таблицах), то вторая встречается впервые, но при этом предоставляет удобное средство защиты данных.
Если функция создана с опцией SCHEMABINDING, то объекты базы данных, на которые ссылается функция, не могут быть изменены (с использованием оператора ALTER) или удалены (с помощью оператора DROP). Например, следующая функция использует таблицу tbPeoples и при этом используется опция SCHEMABINDING:
Функция может быть связанной со схемой, только если следующие ограничения истины:
- все функции объявленные пользователем и просмотрщики на которые ссылается функция, также связаны со схемой с помощью опции SCHEMABINDING;
- объекты, на которые ссылается функция, должны использовать имя из двух частей именования: owner.objectname. При создании функции GetPeoples2 ссылка на таблицу указана именно в таком формате – dbo.tbPeoples;
- Функция и объекты должны быть расположены в одной базе данных;
- Пользователь, который создает функцию, имеет право доступа ко всем объектам, на которые ссылается функция.
Создайте функцию и попробуйте после этого удалить таблицу tbPeoples.
В ответ на это сервер выдаст сообщение с ошибкой о том, что объект не может быть удален, из-за присутствия внешнего ключа. Даже если избавиться от ключа, удаление будет невозможно, потому что на таблицу ссылается функция, привязанная к схеме.
Чтобы увидеть сообщение без удаления ключа, давайте добавим к таблице колонку, а потом попробуем ее удалить:
Создание пройдет успешно, а вот во время удаления произойдет ошибка, с сообщением о том, что существует ограничение, которое зависит от колонки. Мы же не создавали никаких ограничений, а просто добавили колонку и попытались ее удалить. Ограничение уже давно существует, но не на отдельную колонку, а на все колонки таблицы и это ограничение создано функцией GetPeoples2, которая связана со схемой.
3.3.7. Изменение функций
Вы можете изменять функцию с помощью оператора ALTER FUNCTION. Общий вид для каждого варианта функции отличается. Давайте рассмотрим каждый из них.
1. Общий вид команды изменения скалярной функции:
2. Общий вид изменения функции, возвращающей таблицу:
3. Общий вид команды изменения функции с множеством операторов, возвращающей таблицу.
Следующий пример показывает упрощенный вариант команды, изменяющей функцию:
3.3.8. Удаления функций
Если вы внимательно читали об объектах просмотра и функциях, то не трудно догадаться, как можно удалить функцию. Конечно же для этого используется оператор DROP FUNCTION:
7) Переменная SQL Server
В MS SQL переменные – это объект, который выступает в качестве заполнителя для области памяти. Переменная содержит одно значение данных.
В этом уроке вы узнаете:
Типы переменных: локальные, глобальные
MS SQL имеет два типа переменных:
- Локальная переменная
- Глобальная переменная.
Однако пользователь может создать только локальную переменную.
Ниже на рисунке показаны два типа переменных, доступных на сервере MS SQL.

Локальная переменная:
- Пользователь объявляет локальную переменную.
- По умолчанию локальная переменная начинается с @.
- Каждая область локальной переменной имеет ограничение на текущий пакет или процедуру в пределах любого данного сеанса.
Глобальная переменная:
- Система поддерживает глобальную переменную . Пользователь не может их объявить.
- Глобальная переменная начинается с @@
- Он хранит информацию о сеансе .
Как ОБЪЯВИТЬ переменную
- Перед использованием любой переменной в пакете или процедуре, вам необходимо объявить переменную.
- Команда DECLARE используется для переменной DECLARE, которая выступает в качестве заполнителя для ячейки памяти.
- Только после того, как объявление сделано, переменная может использоваться в последующей части пакета или процедуры.
Синтаксис TSQL:
Правила:
- Инициализация – необязательная вещь при объявлении.
- По умолчанию, DECLARE инициализирует переменную в NULL.
- Использование ключевого слова «AS» необязательно.
- Чтобы объявить более одной локальной переменной, используйте запятую после определения первой локальной переменной, а затем определите имя следующей локальной переменной и тип данных.
Примеры объявления переменной:
Запрос: с «КАК»
Запрос: без ‘AS’
Запрос: ОБЪЯВИТЬ две переменные
Присвоение значения переменному
Вы можете присвоить значение переменной следующими тремя способами :
- При объявлении переменной используется ключевое слово DECLARE.
- Использование SET
- Использование SELECT
Давайте посмотрим на все три способа в деталях:
При объявлении переменной используется ключевое слово DECLARE.
Синтаксис T-SQL:
Здесь после типа данных мы можем использовать ‘=’, за которым следует присвоить значение
Запрос:
Использование SET
Иногда мы хотим разделить объявление и инициализацию. SET может использоваться для назначения значений переменной, после объявления переменной. Ниже приведены различные способы назначения значений с помощью SET:
Пример : присвоение значения переменной с помощью SET
Синтаксис:
Запрос:
Пример : присвоить значение нескольким переменным с помощью SET.
Синтаксис:
Правило: одно ключевое слово SET может использоваться для присвоения значения только одной переменной .
Запрос:
Пример : присвоение значения переменной с помощью скалярного подзапроса с помощью SET
Синтаксис:
Правила:
- Заключите запрос в скобки.
- Запрос должен быть скалярным запросом. Скалярный запрос – это запрос с результатами в виде одной строки и одного столбца. В противном случае запрос выдаст ошибку.
- Если запрос возвращает ноль строк, то для переменной устанавливается значение EMPTY, т.е. NULL.
Предположение: предположим, что у нас есть таблица «Guru99» с двумя столбцами, как показано ниже:
Мы будем использовать таблицу «Guru99» в дальнейших уроках
Пример 1: Когда подзапрос возвращает одну строку в результате.
Пример 2: когда подзапрос возвращает нулевую строку в результате
В данном конкретном случае значением переменной является ПУСТО, то есть ПУСТО (NULL).
ИСПОЛЬЗОВАНИЕ ВЫБРАТЬ
Так же, как SET, мы также можем использовать SELECT для присвоения значений переменным, после объявления переменной с помощью DECLARE. Ниже приведены различные способы присвоения значения с помощью SELECT:
Пример : присвоение значения переменной с помощью SELECT
Синтаксис:
Запрос:
Пример : присвоение значения нескольким переменным с помощью SELECT
Синтаксис:
Правила: В отличие от SET, SELECT может использоваться для присвоения значения нескольким переменным, разделенным запятой .
Пример : присвоение значения переменной с помощью подзапроса с помощью SELECT
Синтаксис:
Правила:
- Заключите запрос в круглые скобки.
- Запрос должен быть скалярным запросом. Скалярный запрос – это запрос с результатом в виде одной строки и одного столбца. В противном случае запрос выдаст ошибку.
- Если запрос возвращает ноль строк, то переменная имеет значение EMPTY, то есть NULL.
- Пересмотрите нашу таблицу ‘Guru99’
Пример 1: Когда подзапрос возвращает одну строку в результате.
Пример 2: когда подзапрос возвращает нулевую строку в результате
В данном конкретном случае переменная имеет значение ПУСТО, то есть NULL.
Пример 3. Присвойте значение переменной с помощью регулярного оператора SELECT.
Синтаксис:
Правила:
- В отличие от SET, если запрос приводит к нескольким строкам, тогда значение переменной устанавливается равным значению последней строки.
- Если запрос возвращает ноль строк, то для переменной устанавливается значение EMPTY, т.е. NULL.
Запрос 1: запрос возвращает одну строку.
Запрос 2: запрос возвращает несколько строк.
В этом особом случае значение переменной устанавливается равным значению последней строки .