Основы SQL

Функции пользователя

Разбить на страницы
Показывать лекцию целиком

Понятие функции пользователя

При реализации на языке SQL сложных алгоритмов, которые могут потребоваться более одного раза, сразу встает вопрос о сохранении разработанного кода для дальнейшего применения. Эту задачу можно было бы реализовать с помощью хранимых процедур, однако их архитектура не позволяет использовать процедуры непосредственно в выражениях, т.к. они требуют промежуточного присвоения возвращенного значения переменной, которая затем и указывается в выражении. Естественно, подобный метод применения программного кода не слишком удобен. Многие разработчики уже давно хотели иметь возможность вызова разработанных алгоритмов непосредственно в выражениях.

Возможность создания пользовательских функций была предоставлена в среде MS SQL Server 2000. В других реализациях SQL в распоряжении пользователя имеются только встроенные функции, которые обеспечивают выполнение наиболее распространенных алгоритмов: поиск максимального или минимального значения и др.

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

В SQL Server имеются следующие классы функций пользователя:

  • Scalarфункции возвращают обычное скалярное значение, каждая может включать множество команд, объединяемых в один блок с помощью конструкции BEGIN...END;
  • Inlineфункции содержат всего одну команду SELECT и возвращают пользователю набор данных в виде значения типа данных TABLE ;
  • Multi-statementфункции также возвращают пользователю значение типа данных TABLE, содержащее набор данных, однако в теле функции находится множество команд SQL ( INSERT, UPDATE и т.д.). Именно с их помощью и формируется набор данных, который должен быть возвращен после выполнения функции .
  • Пользовательские функции сходны с хранимыми процедурами, но, в отличие от них, могут применяться в запросах так же, как и системные встроенные функции. Пользовательские функции, возвращающие таблицы, могут стать альтернативой просмотрам. Просмотры ограничены одним выражением SELECT, а пользовательские функции способны включать дополнительные выражения, что позволяет создавать более сложные и мощные конструкции.

    Функции Scalar

    Создание и изменение функции данного типа выполняется с помощью команды:

    <определение_скаляр_функции>::=
    {CREATE | ALTER } FUNCTION [владелец.]
        имя_функции
    ( [ { @имя_параметра скаляр_тип_данных
        [=default]}[,...n]])
    RETURNS скаляр_тип_данных
    [WITH {ENCRYPTION | SCHEMABINDING}
        [,...n] ]
    [AS]
    BEGIN
    <тело_функции>
    RETURN скаляр_выражение
    END

    Рассмотрим назначение параметров команды.

    Функция может содержать один или несколько входных параметров либо не содержать ни одного. Каждый параметр должен иметь уникальное в пределах создаваемой функции имя и начинаться с символа " @ ". После имени указывается тип данных параметра. Дополнительно можно указать значение, которое будет автоматически присваиваться параметру ( DEFAULT ), если пользователь явно не указал значение соответствующего параметра при вызове функции.

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

    Дополнительные параметры, с которыми должна быть создана функция, могут быть указаны посредством ключевого слова WITH. Благодаря ключевому слову ENCRYPTION код команды, используемый для создания функции, будет зашифрован, и никто не сможет просмотреть его. Эта возможность позволяет скрыть логику работы функции. Кроме того, в теле функции может выполняться обращение к различным объектам базы данных, а потому изменение или удаление соответствующих объектов может привести к нарушению работы функции. Чтобы избежать этого, требуется запретить внесение изменений, указав при создании этой функции ключевое слово SCHEMABINDING.

    Между ключевыми словами BEGIN...END указывается набор команд, они и будут являться телом функции.

    Когда в ходе выполнения кода функции встречается ключевое слово RETURN, выполнение функции завершается и как результат ее вычисления возвращается значение, указанное непосредственно после слова RETURN. Отметим, что в теле функции разрешается использование множества команд RETURN, которые могут возвращать различные значения. В качестве возвращаемого значения допускаются как обычные константы, так и сложные выражения. Единственное условие – тип данных возвращаемого значения должен совпадать с типом данных, указанным после ключевого слова RETURNS.

    Пример 11.1. Создать и применить функцию скалярного типа для вычисления суммарного количества товара, поступившего за определенную дату. Владелец функции – пользователь с именем user1.

    CREATE FUNCTION
        user1.sales(@data DATETIME)
    RETURNS INT
    AS
    BEGIN
    DECLARE @c INT
    SET @c=(SELECT SUM(количество)
            FROM Сделка
            WHERE дата=@data)
    RETURN (@c)
    END

    В качестве входного параметра используется дата. Функция возвращает значение целого типа, полученное из оператора SELECT путем суммирования количества товара из таблицы Сделка. Условием отбора записей для суммирования является равенство даты сделки значению входного параметра функции.

    Проиллюстрируем обращение к функции пользователя: определим количество товара, поступившего за 02.11.01:

    DECLARE @kol INT
    SET @kol=user1.sales ('02.11.01')
    SELECT @kol

    Функции Inline

    Создание и изменение функции этого типа выполняется с помощью команды:

    <определение_табл_функции>::=
    {CREATE | ALTER } FUNCTION [владелец.]
        имя_функции
    ( [ { @имя_параметра скаляр_тип_данных
        [=default]}[,...n]])
    RETURNS TABLE
    [ WITH {ENCRYPTION | SCHEMABINDING}
        [,...n] ]
    [AS]
    RETURN [(] SELECT_оператор [)]

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

    После ключевого слова RETURNS всегда должно указываться ключевое слово TABLE. Таким образом, функция данного типа должна строго возвращать значение типа данных TABLE. Структура возвращаемого значения типа TABLE не указывается явно при описании собственно типа данных. Вместо этого сервер будет автоматически использовать для возвращаемого значения TABLE структуру, возвращаемую запросом SELECT, который является единственной командой функции.

    Особенность функции данного типа заключается в том, что структура значения TABLE создается автоматически в ходе выполнения запроса, а не указывается явно при определении типа после ключевого слова RETURNS.

    Возвращаемое функцией значение типа TABLE может быть использовано непосредственно в запросе, т.е. в разделе FROM.

    Пример 11.2. Создать и применить функцию табличного типа для определения двух наименований товара с наибольшим остатком.

    CREATE FUNCTION user1.itog()
    RETURNS TABLE
    AS
    RETURN (SELECT TOP 2 Товар.Название
       FROM Товар INNER JOIN Склад  
       ON Товар.КодТовара=Склад.КодТовара
       ORDER BY Склад.Остаток DESC)

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

    SELECT Название
    FROM user1.itog()

    Функции Multi-statement

    Создание и изменение функций типа Multi-statement выполняется с помощью следующей команды:

    <определение_мульти_функции>::=
    {CREATE | ALTER }FUNCTION [владелец.]
        имя_функции
    ( [ { @имя_параметра скаляр_тип_данных
        [=default]}[,...n]])
    RETURNS @имя_параметра TABLE
        <определение_таблицы> 
    [WITH {ENCRYPTION | SCHEMABINDING}
        [,...n] ]
    [AS]
    BEGIN
    <тело_функции>
    RETURN 
    END

    Использование большей части параметров рассматривалось при описании предыдущих функций.

    Отметим, что функции данного типа, как и табличные, возвращают значение типа TABLE. Однако, в отличие от табличных функций, при создании функций Multi-statement необходимо явно задать структуру возвращаемого значения. Она указывается непосредственно после ключевого слова TABLE и, таким образом, является частью определения возвращаемого типа данных. Синтаксис конструкции <определение_таблицы> полностью соответствует одноименным структурам, используемым при создании обычных таблиц с помощью команды CREATE TABLE.

    Набор возвращаемых данных должен формироваться с помощью команд INSERT, выполняемых в теле функции. Кроме того, в теле функции допускается использование различных конструкций языка SQL, которые могут контролировать значения, размещаемые в выходном наборе строк. При работе с командой INSERT требуется явно указать имя того объекта, куда необходимо вставить строки. Поэтому в функциях типа Multi-statement, в отличие от табличных, необходимо присвоить какое-то имя объекту с типом данных TABLE – оно и указывается как возвращаемое значение.

    Завершение работы функции происходит в двух случаях: если возникают ошибки выполнения и если появляется ключевое слово RETURN. В отличие от функций скалярного типа, при использовании команды RETURN не нужно указывать возвращаемое значение. Сервер автоматически возвратит набор данных типа TABLE, имя и структура которого была указана после ключевого слова RETURNS. В теле функции может быть указано более одной команды RETURN.

    Необходимо отметить, что работа функции завершается только при наличии команды RETURN. Это утверждение верно и в том случае, когда речь идет о достижении конца тела функции – самой последней командой должна быть команда RETURN.

    Пример 11.3. Создать и применить функцию (типа multi-statement), которая для некоторого сотрудника выводит список всех его подчиненных (подчиненных как непосредственно ему, так и опосредствованно через других сотрудников).

    Список сотрудников с указанием каждого руководителя представлен в таблице emp_mgr со следующей структурой:

    CREATE TABLE emp_mgr
    (emp CHAR(2) PRIMARY KEY,-- сотрудник
    mgr CHAR(2))             -- руководитель

    Пример данных в таблице emp_mgr показан ниже. Для упрощения иллюстрации имена сотрудников и их начальников представлены буквами латинского алфавита. У директора организации начальника нет ( NULL ).

    emp     mgr
    ---------
    a     NULL
    b     a
    c     a
    d     a
    e     f
    f     b
    g     b
    i     c
    k     d
     
    CREATE FUNCTION fn_findReports(@id_emp
        CHAR(2))
    RETURNS @report TABLE(empid CHAR(2)
        PRIMARY KEY, 
        mgrid CHAR(2))
    AS
    BEGIN
        DECLARE @r INT
        DECLARE @t TABLE(empid CHAR(2)
            PRIMARY KEY, 
            mgrid CHAR(2), 
               pr   INT DEFAULT 0)
    INSERT @t SELECT emp,mgr,0
            FROM emp_mgr
            WHERE emp=@id_emp
    SET @r=@@ROWCOUNT
    WHILE @r>0
    BEGIN
        UPDATE @t   SET pr=1   WHERE pr=0
        INSERT @t SELECT e.emp, e.mgr,0  
            FROM  emp_mgr e, @t t 
            WHERE e.mgr=t.empid
                AND t.pr=1
        SET @r=@@ROWCOUNT
        UPDATE @t SET pr=2 WHERE pr=1
    END
    INSERT @report SELECT empid, mgrid
        FROM @t
    RETURN 
    END

    Применим созданную функцию для определения списка подчиненных сотрудника ‘b’:

    SELECT * FROM fn_findReports('b')

    Оператор возвращает следующие значения:

    emp     mgr
    -----------
    b     a 
    e     f 
    f     b 
    g     b

    Список подчиненных сотрудника ‘a’ создается с помощью оператора

    SELECT * FROM fn_findReports('a')
    
    
    emp     mgr
    ---------
    a     NULL
    b     a
    c     a
    d     a
    e     f
    f     b
    g     b
    i     c
    k     d

    Другой оператор формирует список подчиненных сотрудника ‘e’:

    SELECT * FROM fn_findReports('e')
    emp     mgr
    --------
    e     f

    Список подчиненных сотрудника ‘c’ создает следующий оператор:

    SELECT * FROM fn_findReports('c')
    emp     mgr
    --------
    c     a
    i     c

    Удаление любой функции осуществляется командой:

    DROP FUNCTION {[ владелец.] имя_функции }
        [,...n]

    Встроенные функции

    Встроенные функции, имеющиеся в распоряжении пользователей при работе с SQL, можно условно разделить на следующие группы:

  • математические функции ;
  • строковые функции ;
  • функции для работы с датой и временем ;
  • функции конфигурирования;
  • функции системы безопасности;
  • функции управления метаданными;
  • статистические функции.
  • Математические функции

    Краткий обзор математических функций представлен в таблице.

    ABS вычисляет абсолютное значение числа
    ACOS вычисляет арккосинус
    ASIN вычисляет арксинус
    ATAN вычисляет арктангенс
    ATN2 вычисляет арктангенс с учетом квадратов
    CEILING выполняет округление вверх
    COS вычисляет косинус угла
    COT возвращает котангенс угла
    DEGREES преобразует значение угла из радиан в градусы
    EXP возвращает экспоненту
    FLOOR выполняет округление вниз
    LOG вычисляет натуральный логарифм
    LOG10 вычисляет десятичный логарифм
    PI возвращает значение "пи"
    POWER возводит число в степень
    RADIANS преобразует значение угла из градуса в радианы
    RAND возвращает случайное число
    ROUND выполняет округление с заданной точностью
    SIGN определяет знак числа
    SIN вычисляет синус угла
    SQUARE выполняет возведение числа в квадрат
    SQRT извлекает квадратный корень
    TAN возвращает тангенс угла
    SELECT Товар.Название, Сделка.Количество,
    Round(Товар.Цена*Сделка.Количество
        *0.05,1)
    AS Налог
    FROM Товар INNER JOIN Сделка
        ON Товар.КодТовара=
        Сделка.КодТовара

    Строковые функции

    Краткий обзор строковых функций представлен в таблице.

    ASCII возвращает код ASCII левого символа строки
    CHAR по коду ASCII возвращает символ
    CHARINDEX определяет порядковый номер символа, с которого начинается вхождение подстроки в строку
    DIFFERENCE возвращает показатель совпадения строк
    LEFT возвращает указанное число символов с начала строки
    LEN возвращает длину строки
    LOWER переводит все символы строки в нижний регистр
    LTRIM удаляет пробелы в начале строки
    NCHAR возвращает по коду символ Unicode
    PATINDEX выполняет поиск подстроки в строке по указанному шаблону
    REPLACE заменяет вхождения подстроки на указанное значение
    QUOTENAME конвертирует строку в формат Unicode
    REPLICATE выполняет тиражирование строки определенное число раз
    REVERSE возвращает строку, символы которой записаны в обратном порядке
    RIGHT возвращает указанное число символов с конца строки
    RTRIM удаляет пробелы в конце строки
    SOUNDEX возвращает код звучания строки
    SPACE возвращает указанное число пробелов
    STR выполняет конвертирование значения числового типа в символьный формат
    STUFF удаляет указанное число символов, заменяя новой подстрокой
    SUBSTRING возвращает для строки подстроку указанной длины с заданного символа
    UNICODE возвращает Unicode-код левого символа строки
    UPPER переводит все символы строки в верхний регистр
    SELECT Фирма, [Фамилия]+""
        +Left([Имя],1)+"."
        +Left([Отчество],1)
        +"." AS ФИО
    FROM Клиент

    Функции для работы с датой и временем

    Краткий обзор основных функций для работы с датой и временем представлен в таблице.

    DATEADD добавляет к дате указанное значение дней, месяцев, часов и т.д.
    DATEDIFF возвращает разницу между указанными частями двух дат
    DATENAME выделяет из даты указанную часть и возвращает ее в символьном формате
    DATEPART выделяет из даты указанную часть и возвращает ее в числовом формате
    DAY возвращает число из указанной даты
    GETDATE возвращает текущее системное время
    ISDATE проверяет правильность выражения на соответствие одному из возможных форматов ввода даты
    MONTH возвращает значение месяца из указанной даты
    YEAR возвращает значение года из указанной даты
    SELECT Year(Дата) AS Год, Month(Дата)
       AS Месяц,
       Sum(Количество) AS Общ_Количество
    FROM Сделка
    GROUP BY Year(Дата), Month(Дата)
    DECLARE @d DATETIME
    DECLARE @y INT
    SET @d=’29.10.03’
    SET @y=DATEPART(yy,@d)
    SELECT @y
    Страницы:

    Понятие функции пользователя

    При реализации на языке SQL сложных алгоритмов, которые могут потребоваться более одного раза, сразу встает вопрос о сохранении разработанного кода для дальнейшего применения. Эту задачу можно было бы реализовать с помощью хранимых процедур, однако их архитектура не позволяет использовать процедуры непосредственно в выражениях, т.к. они требуют промежуточного присвоения возвращенного значения переменной, которая затем и указывается в выражении. Естественно, подобный метод применения программного кода не слишком удобен. Многие разработчики уже давно хотели иметь возможность вызова разработанных алгоритмов непосредственно в выражениях.

    Возможность создания пользовательских функций была предоставлена в среде MS SQL Server 2000. В других реализациях SQL в распоряжении пользователя имеются только встроенные функции, которые обеспечивают выполнение наиболее распространенных алгоритмов: поиск максимального или минимального значения и др.

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

    В SQL Server имеются следующие классы функций пользователя:

  • Scalarфункции возвращают обычное скалярное значение, каждая может включать множество команд, объединяемых в один блок с помощью конструкции BEGIN...END;
  • Inlineфункции содержат всего одну команду SELECT и возвращают пользователю набор данных в виде значения типа данных TABLE ;
  • Multi-statementфункции также возвращают пользователю значение типа данных TABLE, содержащее набор данных, однако в теле функции находится множество команд SQL ( INSERT, UPDATE и т.д.). Именно с их помощью и формируется набор данных, который должен быть возвращен после выполнения функции .
  • Пользовательские функции сходны с хранимыми процедурами, но, в отличие от них, могут применяться в запросах так же, как и системные встроенные функции. Пользовательские функции, возвращающие таблицы, могут стать альтернативой просмотрам. Просмотры ограничены одним выражением SELECT, а пользовательские функции способны включать дополнительные выражения, что позволяет создавать более сложные и мощные конструкции.

    Функции Scalar

    Создание и изменение функции данного типа выполняется с помощью команды:

    <определение_скаляр_функции>::=
    {CREATE | ALTER } FUNCTION [владелец.]
        имя_функции
    ( [ { @имя_параметра скаляр_тип_данных
        [=default]}[,...n]])
    RETURNS скаляр_тип_данных
    [WITH {ENCRYPTION | SCHEMABINDING}
        [,...n] ]
    [AS]
    BEGIN
    <тело_функции>
    RETURN скаляр_выражение
    END

    Рассмотрим назначение параметров команды.

    Функция может содержать один или несколько входных параметров либо не содержать ни одного. Каждый параметр должен иметь уникальное в пределах создаваемой функции имя и начинаться с символа " @ ". После имени указывается тип данных параметра. Дополнительно можно указать значение, которое будет автоматически присваиваться параметру ( DEFAULT ), если пользователь явно не указал значение соответствующего параметра при вызове функции.

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

    Дополнительные параметры, с которыми должна быть создана функция, могут быть указаны посредством ключевого слова WITH. Благодаря ключевому слову ENCRYPTION код команды, используемый для создания функции, будет зашифрован, и никто не сможет просмотреть его. Эта возможность позволяет скрыть логику работы функции. Кроме того, в теле функции может выполняться обращение к различным объектам базы данных, а потому изменение или удаление соответствующих объектов может привести к нарушению работы функции. Чтобы избежать этого, требуется запретить внесение изменений, указав при создании этой функции ключевое слово SCHEMABINDING.

    Между ключевыми словами BEGIN...END указывается набор команд, они и будут являться телом функции.

    Когда в ходе выполнения кода функции встречается ключевое слово RETURN, выполнение функции завершается и как результат ее вычисления возвращается значение, указанное непосредственно после слова RETURN. Отметим, что в теле функции разрешается использование множества команд RETURN, которые могут возвращать различные значения. В качестве возвращаемого значения допускаются как обычные константы, так и сложные выражения. Единственное условие – тип данных возвращаемого значения должен совпадать с типом данных, указанным после ключевого слова RETURNS.

    Пример 11.1. Создать и применить функцию скалярного типа для вычисления суммарного количества товара, поступившего за определенную дату. Владелец функции – пользователь с именем user1.

    CREATE FUNCTION
        user1.sales(@data DATETIME)
    RETURNS INT
    AS
    BEGIN
    DECLARE @c INT
    SET @c=(SELECT SUM(количество)
            FROM Сделка
            WHERE дата=@data)
    RETURN (@c)
    END

    В качестве входного параметра используется дата. Функция возвращает значение целого типа, полученное из оператора SELECT путем суммирования количества товара из таблицы Сделка. Условием отбора записей для суммирования является равенство даты сделки значению входного параметра функции.

    Проиллюстрируем обращение к функции пользователя: определим количество товара, поступившего за 02.11.01:

    DECLARE @kol INT
    SET @kol=user1.sales ('02.11.01')
    SELECT @kol

    Функции Inline

    Создание и изменение функции этого типа выполняется с помощью команды:

    <определение_табл_функции>::=
    {CREATE | ALTER } FUNCTION [владелец.]
        имя_функции
    ( [ { @имя_параметра скаляр_тип_данных
        [=default]}[,...n]])
    RETURNS TABLE
    [ WITH {ENCRYPTION | SCHEMABINDING}
        [,...n] ]
    [AS]
    RETURN [(] SELECT_оператор [)]

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

    После ключевого слова RETURNS всегда должно указываться ключевое слово TABLE. Таким образом, функция данного типа должна строго возвращать значение типа данных TABLE. Структура возвращаемого значения типа TABLE не указывается явно при описании собственно типа данных. Вместо этого сервер будет автоматически использовать для возвращаемого значения TABLE структуру, возвращаемую запросом SELECT, который является единственной командой функции.

    Особенность функции данного типа заключается в том, что структура значения TABLE создается автоматически в ходе выполнения запроса, а не указывается явно при определении типа после ключевого слова RETURNS.

    Возвращаемое функцией значение типа TABLE может быть использовано непосредственно в запросе, т.е. в разделе FROM.

    Пример 11.2. Создать и применить функцию табличного типа для определения двух наименований товара с наибольшим остатком.

    CREATE FUNCTION user1.itog()
    RETURNS TABLE
    AS
    RETURN (SELECT TOP 2 Товар.Название
       FROM Товар INNER JOIN Склад  
       ON Товар.КодТовара=Склад.КодТовара
       ORDER BY Склад.Остаток DESC)

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

    SELECT Название
    FROM user1.itog()

    Функции Multi-statement

    Создание и изменение функций типа Multi-statement выполняется с помощью следующей команды:

    <определение_мульти_функции>::=
    {CREATE | ALTER }FUNCTION [владелец.]
        имя_функции
    ( [ { @имя_параметра скаляр_тип_данных
        [=default]}[,...n]])
    RETURNS @имя_параметра TABLE
        <определение_таблицы> 
    [WITH {ENCRYPTION | SCHEMABINDING}
        [,...n] ]
    [AS]
    BEGIN
    <тело_функции>
    RETURN 
    END

    Использование большей части параметров рассматривалось при описании предыдущих функций.

    Отметим, что функции данного типа, как и табличные, возвращают значение типа TABLE. Однако, в отличие от табличных функций, при создании функций Multi-statement необходимо явно задать структуру возвращаемого значения. Она указывается непосредственно после ключевого слова TABLE и, таким образом, является частью определения возвращаемого типа данных. Синтаксис конструкции <определение_таблицы> полностью соответствует одноименным структурам, используемым при создании обычных таблиц с помощью команды CREATE TABLE.

    Набор возвращаемых данных должен формироваться с помощью команд INSERT, выполняемых в теле функции. Кроме того, в теле функции допускается использование различных конструкций языка SQL, которые могут контролировать значения, размещаемые в выходном наборе строк. При работе с командой INSERT требуется явно указать имя того объекта, куда необходимо вставить строки. Поэтому в функциях типа Multi-statement, в отличие от табличных, необходимо присвоить какое-то имя объекту с типом данных TABLE – оно и указывается как возвращаемое значение.

    Завершение работы функции происходит в двух случаях: если возникают ошибки выполнения и если появляется ключевое слово RETURN. В отличие от функций скалярного типа, при использовании команды RETURN не нужно указывать возвращаемое значение. Сервер автоматически возвратит набор данных типа TABLE, имя и структура которого была указана после ключевого слова RETURNS. В теле функции может быть указано более одной команды RETURN.

    Необходимо отметить, что работа функции завершается только при наличии команды RETURN. Это утверждение верно и в том случае, когда речь идет о достижении конца тела функции – самой последней командой должна быть команда RETURN.

    Пример 11.3. Создать и применить функцию (типа multi-statement), которая для некоторого сотрудника выводит список всех его подчиненных (подчиненных как непосредственно ему, так и опосредствованно через других сотрудников).

    Список сотрудников с указанием каждого руководителя представлен в таблице emp_mgr со следующей структурой:

    CREATE TABLE emp_mgr
    (emp CHAR(2) PRIMARY KEY,-- сотрудник
    mgr CHAR(2))             -- руководитель

    Пример данных в таблице emp_mgr показан ниже. Для упрощения иллюстрации имена сотрудников и их начальников представлены буквами латинского алфавита. У директора организации начальника нет ( NULL ).

    emp     mgr
    ---------
    a     NULL
    b     a
    c     a
    d     a
    e     f
    f     b
    g     b
    i     c
    k     d
     
    CREATE FUNCTION fn_findReports(@id_emp
        CHAR(2))
    RETURNS @report TABLE(empid CHAR(2)
        PRIMARY KEY, 
        mgrid CHAR(2))
    AS
    BEGIN
        DECLARE @r INT
        DECLARE @t TABLE(empid CHAR(2)
            PRIMARY KEY, 
            mgrid CHAR(2), 
               pr   INT DEFAULT 0)
    INSERT @t SELECT emp,mgr,0
            FROM emp_mgr
            WHERE emp=@id_emp
    SET @r=@@ROWCOUNT
    WHILE @r>0
    BEGIN
        UPDATE @t   SET pr=1   WHERE pr=0
        INSERT @t SELECT e.emp, e.mgr,0  
            FROM  emp_mgr e, @t t 
            WHERE e.mgr=t.empid
                AND t.pr=1
        SET @r=@@ROWCOUNT
        UPDATE @t SET pr=2 WHERE pr=1
    END
    INSERT @report SELECT empid, mgrid
        FROM @t
    RETURN 
    END

    Применим созданную функцию для определения списка подчиненных сотрудника ‘b’:

    SELECT * FROM fn_findReports('b')

    Оператор возвращает следующие значения:

    emp     mgr
    -----------
    b     a 
    e     f 
    f     b 
    g     b

    Список подчиненных сотрудника ‘a’ создается с помощью оператора

    SELECT * FROM fn_findReports('a')
    
    
    emp     mgr
    ---------
    a     NULL
    b     a
    c     a
    d     a
    e     f
    f     b
    g     b
    i     c
    k     d

    Другой оператор формирует список подчиненных сотрудника ‘e’:

    SELECT * FROM fn_findReports('e')
    emp     mgr
    --------
    e     f

    Список подчиненных сотрудника ‘c’ создает следующий оператор:

    SELECT * FROM fn_findReports('c')
    emp     mgr
    --------
    c     a
    i     c

    Удаление любой функции осуществляется командой:

    DROP FUNCTION {[ владелец.] имя_функции }
        [,...n]

    Встроенные функции

    Встроенные функции, имеющиеся в распоряжении пользователей при работе с SQL, можно условно разделить на следующие группы:

  • математические функции ;
  • строковые функции ;
  • функции для работы с датой и временем ;
  • функции конфигурирования;
  • функции системы безопасности;
  • функции управления метаданными;
  • статистические функции.
  • Математические функции

    Краткий обзор математических функций представлен в таблице.

    ABS вычисляет абсолютное значение числа
    ACOS вычисляет арккосинус
    ASIN вычисляет арксинус
    ATAN вычисляет арктангенс
    ATN2 вычисляет арктангенс с учетом квадратов
    CEILING выполняет округление вверх
    COS вычисляет косинус угла
    COT возвращает котангенс угла
    DEGREES преобразует значение угла из радиан в градусы
    EXP возвращает экспоненту
    FLOOR выполняет округление вниз
    LOG вычисляет натуральный логарифм
    LOG10 вычисляет десятичный логарифм
    PI возвращает значение "пи"
    POWER возводит число в степень
    RADIANS преобразует значение угла из градуса в радианы
    RAND возвращает случайное число
    ROUND выполняет округление с заданной точностью
    SIGN определяет знак числа
    SIN вычисляет синус угла
    SQUARE выполняет возведение числа в квадрат
    SQRT извлекает квадратный корень
    TAN возвращает тангенс угла
    SELECT Товар.Название, Сделка.Количество,
    Round(Товар.Цена*Сделка.Количество
        *0.05,1)
    AS Налог
    FROM Товар INNER JOIN Сделка
        ON Товар.КодТовара=
        Сделка.КодТовара

    Строковые функции

    Краткий обзор строковых функций представлен в таблице.

    ASCII возвращает код ASCII левого символа строки
    CHAR по коду ASCII возвращает символ
    CHARINDEX определяет порядковый номер символа, с которого начинается вхождение подстроки в строку
    DIFFERENCE возвращает показатель совпадения строк
    LEFT возвращает указанное число символов с начала строки
    LEN возвращает длину строки
    LOWER переводит все символы строки в нижний регистр
    LTRIM удаляет пробелы в начале строки
    NCHAR возвращает по коду символ Unicode
    PATINDEX выполняет поиск подстроки в строке по указанному шаблону
    REPLACE заменяет вхождения подстроки на указанное значение
    QUOTENAME конвертирует строку в формат Unicode
    REPLICATE выполняет тиражирование строки определенное число раз
    REVERSE возвращает строку, символы которой записаны в обратном порядке
    RIGHT возвращает указанное число символов с конца строки
    RTRIM удаляет пробелы в конце строки
    SOUNDEX возвращает код звучания строки
    SPACE возвращает указанное число пробелов
    STR выполняет конвертирование значения числового типа в символьный формат
    STUFF удаляет указанное число символов, заменяя новой подстрокой
    SUBSTRING возвращает для строки подстроку указанной длины с заданного символа
    UNICODE возвращает Unicode-код левого символа строки
    UPPER переводит все символы строки в верхний регистр
    SELECT Фирма, [Фамилия]+""
        +Left([Имя],1)+"."
        +Left([Отчество],1)
        +"." AS ФИО
    FROM Клиент

    Функции для работы с датой и временем

    Краткий обзор основных функций для работы с датой и временем представлен в таблице.

    DATEADD добавляет к дате указанное значение дней, месяцев, часов и т.д.
    DATEDIFF возвращает разницу между указанными частями двух дат
    DATENAME выделяет из даты указанную часть и возвращает ее в символьном формате
    DATEPART выделяет из даты указанную часть и возвращает ее в числовом формате
    DAY возвращает число из указанной даты
    GETDATE возвращает текущее системное время
    ISDATE проверяет правильность выражения на соответствие одному из возможных форматов ввода даты
    MONTH возвращает значение месяца из указанной даты
    YEAR возвращает значение года из указанной даты
    SELECT Year(Дата) AS Год, Month(Дата)
       AS Месяц,
       Sum(Количество) AS Общ_Количество
    FROM Сделка
    GROUP BY Year(Дата), Month(Дата)
    DECLARE @d DATETIME
    DECLARE @y INT
    SET @d=’29.10.03’
    SET @y=DATEPART(yy,@d)
    SELECT @y
    Вернуться к учебному плану