
- •Министерство образования Российской Федерации Пензенский государственный университет
- •Пенза 2004
- •Введение
- •1. Архитектура баз данных ms sql Server 2000
- •Физическая архитектура базы данных sql Server 2000
- •1.1.1. Файлы данных и группы файлов
- •1.1.2. Страничная организация файлов данных
- •ЛоГическая архитектура базы данных sql Server 2000
- •1.3. Системные базы данных sql server 2000
- •Создание и сопровождение баз данных средствами enterprise manager
- •3. Создание и сопровождение таблиц баз данных средствами enterprise manager
- •3.1. Основные принципы создания таблиц
- •3.2. Создание, модификация и удаление таблиц средствами Enterprise Manager
- •3.3. Управление диаграммами
- •4. Создание и управление индексами средствами Enterprise manager
- •5. Создание представлений средствами Enterprise manager
- •6. Основы программирования на языке Transact-sql
- •6.1. Средства языка Transact–sql
- •6.2. Константы, имена, идентификаторы, переменные, выражения в языке Transact–sql
- •6.3. Типы данных sql Server 2000
- •6.4. Создание и удаление баз данных, таблиц и представлений
- •6.4.1. Создание и удаление баз данных
- •6.4.2. Создание и удаление таблиц
- •6.4.3. Создание представлений
- •6.5. Создание и управление индексами
- •6.6. Вставка, удаление и изменение данных
- •6.7. Выборка данных
- •Раздел into позволяет создать новую таблицу для хранения результатов запроса, структура которой будет определяться списком выбора, т.Е. Динамически при выполнении запроса.
- •6.8. Функции sql Server 2000
- •6.8.1. Встроенные функции sql Server 2000
- •6.8.2. Функции пользователя
- •6.9. Хранимые процедуры sql Server 2000
- •6.9.1. Создание хранимых процедур
- •6.10. Триггеры
- •6.11. Создание и управление транзакциями
- •6.12. Создание, отладка и оптимизация sql–модулей
- •7. Лабораторный практикум
- •Создание диаграммы базы данных;
- •Рекомендуемые источники Печатные издания
- •Интернет-ресурсы1
- •Приложение 1. Примеры операторов языка Transact-sql
- •1.1. Создание баз данных
- •Create database Archive
- •Use master
- •Filegroup SalesGroup1
- •Filegroup SalesGroup2
- •Create database Sales
- •Create database Employees
- •1.2. Создание таблиц баз данных
- •1.3. Создание индексов
- •1.4. Создание представлений
- •From dbo. Authors
- •1.5. Добавление, модификация и удаление данных в таблицах
- •Insert Into TabF default values
- •Insert Into TabG (Col1,Col2)
- •1.6. Выборка данных из таблиц
- •If update (Phone)
- •Insert into #aaa values (111)
- •Insert into #aaa values (222)
- •Insert into #aaa values (333)
- •1.9. Создание пользовательских функций
- •1.10. Создание хранимых процедур пользователя
- •Приложение 2. Описание предметных областей, схем баз данных и запросов для лабораторного практикума
- •2.1. Предметная область «Летопись острова Санта-Белинда»
- •2.2. Предметная область «Скачки»
- •2.3. Предметная область «Хроника восхождений в альпинистском клубе»
- •2.4. Предметная область базы данных медицинского кооператива
- •2.5. Предметная область базы данных «Городская Дума»
- •2.6. Предметная область базы данных рыболовной фирмы
- •2.7. Предметная область база данных фирмы, проводящей аукционы
- •2.8. Предметная область база данных библиотеки
- •Предметная область базы данных для обслуживания работы конференции
- •2.10. Предметная область базы данных для обслуживания склада
6.8.2. Функции пользователя
В SQL Server 2000 можно создавать функции трех классов:
Scalar – возвращают обычное скалярное значение, любого из типов данных, поддерживаемых SQL Server 2000, за исключением типов данных timestamp, text, ntext, image, table и cursor;
Inline – возвращают таблицу динамической структуры в виде значения типа данных table, создаваемую единственной командой тела функции SELECT;
Multi–statement – возвращает обычную таблицу заданной структуры в виде значения типа данных table, при этом количество команд в теле функции не ограничивается.
Все рассмотренные типы функций могут содержать ни одного, один или более входных параметров одного из поддерживаемых SQL Server 2000 типов данных, за исключением типов данных timestamp, table и cursor. В теле функции (за исключением функций типа Inline) разрешается объявление локальных переменных, использование циклов, ветвлений и любых других программных конструкций. Также разрешается вызов других функций и хранимых процедур и создание внутри функций курсоров.
При использовании в функции команд INSERT, UPDATE и DELETE разрешается работать только с наборами данных, хранящихся в переменных типа table и созданными в теле функции. Помимо указанных ограничений при разработке функций следует учитывать, что они не могут возвращать данные непосредственно клиенту, как это может делать хранимая процедура. То есть не разрешается использование в теле функции команды PRINT, а также команды SELECT для непосредственного возвращения данных. Для получения информации о функции можно использовать хранимую процедуру sp_help "имя_ функции".
Функции Scalar. Создание функций этого типа выполняется с помощью команды CREATE FUNCTION, имеющей следующий синтаксис:
CREATE FUNCTION [ owner_name.] function_name
( [ { @parameter_name scalar_parameter_data_type
[ = default ] } [....n ] ] )
RETURNS scalar_return_data__type
[ WITH < function_option> [,...n] ]
[ AS ]
BEGIN
function_body
RETURN sealar_expression
END
Рассмотрим назначение и использование параметров команды.
[ ownername. ] function_name - c помощью этого параметра указывается имя, которое будет присвоено функции (function_name). Дополнительно можно указать и имя владельца (owner_name), которому будет принадлежать создаваемая функция. Это должно быть имя пользователя или роли, имеющихся в базе данных, в контексте которой создается функция. Если имя владельца опущено, то создаваемая функция будет принадлежать пользователю, выполняющему создание функции. При выборе имени функции следует учитывать, что имя должно быть уникальным в пределах владельца. Более того, не должно существовать объектов, принадлежащих тому же владельцу и имеющих аналогичное имя.
@parameter_name sealar_parameter_data_type [ = default ] -используется для определения входных параметров. Каждый параметр должен иметь имя, уникальное в пределах создаваемой функции, и начинаться с символа @. Имя параметра указывается с помощью аргумента @parameter_name. После имени параметра через пробел необходимо указать тип данных (seal ar_parameter_data_type), который будет иметь параметр. Допускается использование любого из поддерживаемых SQL Server 2000 типов данных, включая пользовательские, за исключением типов данных timestamp (rowversion), cursor и table. Дополнительно можно указать значение (default), которое будет автоматически присваиваться параметру, если пользователь явно не указал значение соответствующего параметра при вызове функции. Естественно, значение по умолчанию должно быть того же тина, что и сам параметр.
RETURNS sсalar_return_data_type - c помощью этой конструкции указывается, какой тип данных будет иметь возвращаемое функцией значение. Слово RETURNS является ключевым и должно присутствовать всегда.
WITH <function_option> [,.. .n] - с помощью ключевого слова WITH могут быть указаны дополнительные параметры, с которыми должна быть создана функция. Параметр указывается с помощью конструкции <function_opt1on>, которая имеет следующий синтаксис:
<function_option>::={ENCRYPTION|SCHEMABINDING}
Благодаря ключевому слову ENCRYPTION код команды CREATE FUNCTION, который был использован для создания функции, будет зашифрован, и никто не сможет просмотреть его. Эта возможность позволяет скрыть логику работы функции. Код команд, который используется для создания объектов базы данных, хранится в столбце text системной таблицы syscomments и без шифрования может быть просмотрен с помощью обычной команды SELECT.
В теле функции может выполняться обращение к различным объектам базы данных. Как следствие этой связи, изменение или удаление соответствующих объектов базы данных может привести к нарушению работы функции. Чтобы запретить внесение изменений в объекты базы данных, которые могут привести к нарушению работы создаваемой функции, требуется указать при создании этой функции ключевое слово SCHEMABINDING.
AS - после этого ключевого слова следует определение собственно тела функции. В принципе, ключевое слово AS может быть опущено.
BEGIN...END - между этими ключевыми словами указывается набор команд (function_body), которые собственно и будут являться телом функции.
RETURN scalar_expression - когда в ходе выполнения кода функции встречается ключевое слово RETURN, выполнение функции завершается и как результат вычисления функции возвращается значение, указанное непосредственно после ключевого слова RETURN. В теле функции разрешается использование множества команд RETURN, которые могут возвращать различные значения. В качестве возвращаемого значения допускаются как обычные константы, так и сложные выражения. Тип данных возвращаемого значения должен совпадать с типом данных, указанных после ключевого слова RETURN.
Функции Inline. Создание функций этого типа выполняется с помощью команды CREATE FUNCTION, имеющей следующий синтаксис:
CREATE FUNCTION [owner_name.] function_name
( [ {@parameter_name scalar_parameter_data_type
[= default] } [,...n ] ] )
RETURNS TABLE
[ WITH <function_option> [ ,...n ] ]
[AS]
RETURN [ ( ] select-stmt [ ) ]
Основная часть параметров, используемая при создании функции типа Inline, аналогична параметрам функций типа Scalar. Тем не менее, создание функций типа Inline имеет свою специфику. После ключевого слова RETURNS всегда должно указываться ключевое слово TABLE. Таким образом, функция Inline должна строго возвращать значение типа данных table. Как видно, структура возвращаемого значение типа table не указывается явно при описании собственно типа данных. Вместо этого сервер будет автоматически использовать для возвращаемого значения table структуру, возвращаемую запросом SELECT, который является единственной командой функции. Код этого запроса задается с помощью аргумента select-stmt. Как видно из синтаксиса команды, код запроса может быть дополнительно помещен в круглые скобки.
Особенностью функции Inline является то, что структура значения table создается динамически в ходе выполнения запроса, а не указывается явно при определении типа после ключевого слова RETURNS. Возвращаемое функцией значение table может быть использовано непосредственно в запросе, то есть в разделе FROM запроса можно указывать непосредственно имя функции со всеми входными параметрами.
Функции Multi-statement. Создание функций этого типа выполняется с помощью команды CREATE FUNCTION, имеющей следующий синтаксис:
CREATE FUNCTION [owner_name.] function_name
( [ { @parameter_name scalar_parameter_data_type
[ = defauTt ] } [ ,...n ] ] )
RETURNS @return_variable TABLE < table_type_definition >
[WITH <function_option> [,...n ]]
[AS]
BEGIN
function_body
RETURN
END
Функции Multi-statement, как и функции Inline, возвращают значение типа table. Однако, в отличие от функций типа Inline, при создании функций Multi-statement необходимо явно задать структуру возвращаемого значения. Эта структура указывается непосредственно после ключевого слова TABLE и, таким образом, является частью определения возвращаемого типа данных. Для описания структуры используется конструкция <table_type_definition>, которая имеет следующий синтаксис:
<table_type_definition> :: =
( { <column_definition> | <table_constraint> } [ ….n ] )
Синтаксис конструкций <col umn_def inition> и <table_constraint> полностью соответствует одноименным структурам, используемым при создании обычных таблиц с помощью команды CREATE TABLE. Набор данных, которые будут возвращены, должен формироваться с помощью команд INSERT, выполняемых в теле функции. В теле функции допускаются различные конструкции Transact-SQL, которые могут контролировать значения, размещаемые в наборе строк (row set). При работе с командой INSERT необходимо явно указать имя объекта, в который необходимо вставить строки. Поэтому в функциях Multi-statement, в отличие от функций Inline, необходимо присвоить какое-то имя значению table. Это имя и указывается с помощью параметра Return_variable.
Завершение работы функции, помимо ошибок выполнения, происходит в случае, когда в коде функции встречается ключевое слово RETURNS. В отличие от функций типа Scalar при использовании команды RETURNS не нужно указывать значение, которое должно быть возвращено. Сервер автоматически возвратит набор данных типа table, имя и структура которого была указана после ключевого слова RETURNS. Напомним, что в теле функции может быть указано более одной команды RETURNS.
Нередко случаются ситуации, когда в довольно хорошо продуманной функции обнаруживаются ошибки. В этом случае возникает необходимость в ее изменении. Помимо того, что причиной изменения функции является ошибка, причиной также может быть и изменение алгоритма работы функции. Помимо этих двух причин можно найти еще несколько, которые требовали бы внесения изменений в функцию. Но уже и так ясно, что пользователь должен иметь возможность внесения изменений в созданные ранее функции.
Изменение функции может быть выполнено двумя способами:
предварительное удаление функции с помощью команды DROP FUNCTION и последующее создание обновленной функции с помощью команды CREATE FUNCTION;
сохранение под именем существующей функции нового кода с помощью команды ALTER FUNCTION.
Первый метод изменения функций связан с определенными проблемами. В частности, если вы потратили довольно много времени на предоставление пользователям права вызова функции, то в случае ее удаления, вся информация о правах доступа к функции будет потеряна. После создания функции с помощью команды CREATE FUNCTION вам нужно будет заново раздавать пользователям права доступа к функции. Помимо проблем с правами доступа, также могут быть затронуты другие объекты базы данных (триггеры, хранимые процедуры или другие функции), использующие в своей работе изменяемую функцию. При последующем создании функция будет являться новым объектом базы данных, имеющем то же имя, что и старая функция, но другой идентификационный номер.
Для избежания описанных проблем при внесении изменений в функцию следует использовать команду ALTER FUNCTION, специально предназначенную для выполнения подобных операций. Эта команда имеет специальный синтаксис для функций каждого типа.
Для изменения функций типа Scalar используется следующий синтаксис:
ALTER FUNCTION [owner_name.] function_name
( [ { @parameter_name scalar_parameter_data_type
[ = default ] } [ ,...n ] ] )
RETURNS scalar_return_data_type
[ WITH < function_option> [,...n] ]
[ AS ]
BEGIN
function_body
RETURN scalar_expression
END
Для изменения функций типа Inline используется следующий синтаксис:
ALTER FUNCTION [owner_name.] function_name
( [ { @parameter_name scalar_parameter_data_type
[ = default ] } [ ,...n ] ] )
RETURNS TABLE
[ WITH < function_option > [ ,...n ] ]
[ AS ]
RETURN [ ( ] select-stmt [ ) ]
Для изменения функций типа Multi-statement используется следующий синтаксис:
ALTER FUNCTION [owner_name.] function_name
( [ { @parameter_name scalar_parameter_data_type
[ = default ] } [ ,...n ] ] )
RETURNS @return_vanable TABLE < table_type_definition >
[WITH < function_option > [ ,…n ] ]
[AS ]
BEGIN
function_body
RETURN
END
Как видно, синтаксис команды ALTER FUNCTION напоминает синтаксис команды CREATE FUNCTION. Действительно, при внесении изменения в функцию пользователь должен указывать полностью весь код функции. В этом плане изменение функции с помощью команды ALTER FUNCTION мало чем отличается от удаления и последующего создания функции, так как объем работы в обоих случаях практически одинаков. Упростить изменение функции помогает системная хранимая процедура sp_helptext, позволяющая получить код Transact-SQL, с помощью которого создан тот или иной объект базы данных. Получить код функции можно только в том случае, если при ее создании не использовался параметр WITH ENCRYPTION. В противном случае из-за шифрования код просмотреть не удастся.
Когда функция становится ненужной, ее можно удалить. Для удаления функций используется команда DROP FUNCTION, имеющая следующий синтаксис:
DROP FUNCTION { [ owner_name. ] function_name } [ ,...n ]
Команда имеет одинаковый синтаксис для всех типов функций. Для удаления функции достаточно указать лишь ее имя. Дополнительно может быть указано еще и имя владельца функции. Это обязательно в случае, если необходимо удалить функцию, принадлежащую не текущему пользователю и не владельцу базы данных (пользователю dbo).
С помощью одной команды DROP FUNCTION можно удалить множество функций, перечислив их имена через запятую. Например, для удаления всех функций, созданных в предыдущих разделах, можно выполнить следующую команду:
DROP FUNCTION Func1, Func2. Func3