Тема 8 - Международный банковский институт

advertisement
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
ТЕМА 8.
ПРАКТИЧЕСКОЕ ЗАНЯТИЕ 1. ВСТРОЕННЫЙ SQL. ПОНЯТИЕ
КУРСОРА.
Цель: изучить изменения в синтаксисе SQL-запросов, вызванные
необходимостью встраивать команды SQL
в базовый язык
программирования.
Для достижения поставленной цели необходимо решить
следующие задачи:
 Изучить принципы изменения синтаксиса SQL-запросов при их
встраивании в программы на базовом языке программирования
 Изучить синтаксис и базовые операторы языка Transact SQL,
используемые при работе с серверными курсорами.
 Научиться применять операторы работы с курсорами для
организации построчной обработки SQL-запросов.
Оглавление.
Основные языковые конструкции Transact SQL ....................................................................2
Выражения в TRANSACT SQL ................................................................................................3
Управляющие операторы........................................................................................................11
Задание 1...................................................................................................................................21
Задание 2...................................................................................................................................21
Результатом работы SQL-запросов является набор данных. Этот
набор данных передается целиком клиенту, подавшему запрос, и
дальше обрабатывается им. Иногда требуется работа не со всем
набором данных, а с одной строкой или с некоторой частью
результирующего набора. Кроме того, передача неограниченного или
большого набора данных на клиент вызывает непроизводительную
загрузку сети, поэтому возникает необходимость непосредственно на
сервере работать с отельными строками. Для обеспечения такого
механизма вводятся новые объекты обработки данных, называемые
курсорами. Курсоры бывают серверные и клиентские. Клиентские
курсоры, получив от сервера результат в виде набора данных,
предоставляют возможность навигации по нему, выбирая по одной
строке и работе с ней. Клиентские курсоры реализуются не на
сервере, а на клиенте. Мы будем говорить про серверные курсоры и в
дальнейшем говоря “курсор” будем иметь ввиду именно их.
Серверный курсор – это механизм, позволяющий работать с
отдельными строками на уровне сервера. Обычно это происходит до
выдачи результата клиенту. Для работы с курсором добавляется
несколько новых операторов SQL. Операторы по работе с курсором
встраиваются в базовый язык программирования конкретного сервера
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
баз данных. На сервере MS SQL Server используется в качестве
базового языка язык Transact SQL.
Основные языковые конструкции Transact SQL
Transact SQL
это базовый язык MS SQL Sever, который
позволяет писать процедуры и функции с использованием операторов
встроенного SQL. Все объекты MS SQL Server 2000 имеют
собственные имена, на которые можно ссылаться в программах – эти
имена называются идентификаторами, в Transact SQL имеются
следующие ограничения на идентификаторы:
 первый символ должен соответствовать стандарту UNICODE
standart 2.0 – один из символов латинского или национального
алфавита либо символом подчеркивания(т.е. нельзя называть ! № ; и
т.д.).
 имена временных таблиц начинаются с символов # или ##;
 имена внутренних переменных начинаются с символа @ для
обозначения глобальных переменных локальных переменных и с
двойного символа @@ для обозначения глобальных переменных;
 нельзя использовать зарезервированные слова в качестве
идентификаторов;
 в именах объектов на MS SQL Server не различается регистр;
 запрещается использовать внутри идентификаторов пробелы и
спец символы !, %, ^, &, -, {, }, ‘ , \, ` ;
 длина имени объектов не должна превышать 128 символов, а
для временных таблиц 116 символов;
 для обхода некоторых ограничений можно заключать имена в
двойные кавычки или в квадратные скобки. В этом случае в качестве
имен могут быть использованы ключевые слова и в идентификаторах
могут
быть
пробелы.
Такие
идентификаторы
называются
«Ограниченными идентификаторами» (Delimited identifiers). Однако
желательно не использовать их в Ваших процедурах и функциях.
Каждый объект в MSSQL Server 2000 создается определенным
пользователем и принадлежит какой-либо базе данных, поэтому
вводится понятие полного квалифицированного (определенного)
имени объекта (full
qualified name). Это имя включает
последовательно, отделенные друг от друга точкой, имена сервера,
базы данных, владельца базы данных и самого объекта.
[[server.] [database ].[owner_name].] object_name
Разрешается пропускать отдельные части, но точки, которые
остаются внутри полного имени, должны оставаться. Например:
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Server…object_name
Owner_name.object_name
Database..object_name
Выражения в TRANSACT SQL
Выражения в языке TransacTransact SQL это комбинация функций,
логических и арифметических операций, констант и других объектов.
Выражения состоят из операндов и операторов. Операндами
выражений могут быть:
 константы например:. 2.45 ‘просто текст’;
 функции;
 имена колонок;
 переменные;
 подзапросы;
 конструкция типа CASE, NULLIF, COALESCE. Все эти
конструкции позволяют использовать логическое условие, для
определения возвращаемого результата.
SQL Server допускает следующие простые операторы (см. табл.1).
Таблица 1.
Примеры простых операторов в Transact SQL
Название
Обозначение, пример
Сложение
+
Set @n=@n+1
Вычитание
Set @m=@n-2
Умножение
*
Деление
/
Остаток от деления
%
Побитное И
&
Побитное ИЛИ
|
Побитное НЕ
~
Исключающее ИЛИ
^
Равно
=
Больше
>
Меньше
<
Больше или равно
>=
Меньше или равно
<=
Неравно
<> или != (нестандартно!)
Не больше
!>
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Не меньше
LEFT OUTER JOIN
RIGHT OUTER JOIN
Конкатенация строк
!<
*= левое внешнее
объединение
=* правое внешнее
объединение
+
‘фамилия’+’ имя ’
Описание переменных
В Transact SQL существует несколько способов хранения и
передачи данных. Одним из таких способов является хранение и
передача данных с использованием переменных. В языке Transact
SQL смысл переменной аналогичен смыслу в других языках, т.е.
переменная – это именованная область памяти, значение которой
может изменяться. То, как сервер будет интерпретировать
последовательность бай памяти, на которые ссылается переменная,
зависит от типа данных, ассоциированных с переменной.
Перед использованием переменной она должна быть объявлена,
для этого существует оператор объявления переменной
DECLARE @<идентификатор переменной> <тип данных>
Единичный знак @ - является признаком локальной переменной.
Локальная переменная видна только в том модуле, где она определена,
при выходе из этого модуля локальная переменная не видна. Для
описания глобальный переменных используется двойной знак @@,
предваряющий имя переменной. Однако следует сказать, что глобальные
переменные активно использует сам сервер, поэтому существует
опасность войти с ним в противоречие.
В одной операторе DECLARE могут быть описаны несколько
переменных, каждое описание отделяется от следующего запятой.
Например:
Declare @n int, @name_s varchar(10)
- мы описали две переменных, одна из них @n имеет целочисленный
типа данных, а вторая @name_s имеет символьный тип данных с
переменной длиной в пределах 10 символов.
Типы данных определяют представление колонок таблиц, параметров
процедур и переменных. В SQL Server помимо предопределенных
системных типов данных можно создавать и пользовательские типы,
основывающиеся на системных. В SQL Server все типы данных
регистонезависимые, в силу чего недопустимо использование различных
пользовательских типов данных, отличающихся только регистром.
Допустимы следующие системные типы данных (см. табл. 2).
Таблица 2.
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Системные типы данных
Вид данных
Двоичные
Символьные
Дата и время
Точное
представление
чисел
Представление
чисел с плавающей
точкой
Целочисленные
типы
Денежные типы
Специальные
Текст и картинки
Синонимы
Денежные типы
Специальные
Текст и картинки
Системное представление
binary[(n)]
varbinary[(n)]
char[(n)]
varchar[(n)]
Datetime
smalldatetime
decimal[(p[, s])]
numeric[(p[, s])]
float[(n)]
real
int - 4 байта
smallint - 2 байта
tinyint -1 байт
Money
smallmoney
Bit
timestamp
типы, определяемые пользователем
Text
image
binary varying для varbinary
character для char
character для char (1)
character (n) для char (n)
character varying (n) для varchar (n)
dec для decimal
integer для int
double precision для float
float [(n)] для n = 1√7 для real
float [(n)] для n = 8√15 для float
Money
smallmoney
Bit
timestamp
типы, определяемые пользователем
Text
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
image
Оператор присваивания значений переменных
Присваивать значения переменным следует с помощью инструкции
SET. Ее синтаксиc:
SET <имя_переменной>=выражение
Здесь выражение должно иметь тот же тип, что и переменная или же
должно допускаться неявное преобразование типов между типом
результата выражения и типом переменной.
Пример1:
DECLARE @a INT, @b VARCHAR(20)
SET @A=3
SET @B=’Тестовая строка’
Можно также записывать значения в переменные с помощью
оператора SELECT. Для этого в разделе SELECT перечисляются
переменные и выражения:
SELECT <имя_переменной>=выражение [, …n]
<дальнейшее описание оператора SELECT>
<дальнейшее описание оператора SELECT> - запрос на языке SQL
Пример2:
DECLARE @N INT, @b VARCHAR (20)
Set @b=’Иванов И.А.’
SELECT @N=N_Reader FROM Readers
Where Name_Reader= @b
В переменную @N будет занесен номер читательского билета
читателя Иванова И.А.
Рекомендуется использовать SELECT для присвоения переменных
только в том случае, если в выражении имеются столбцы таблиц или
представлений, имеющихся в БД, как, например, в приведенном выше
примере. Если выражение включает только константы, переменные и
функции, то следует пользоваться оператором
SET. Также стоит
обратить внимание на то, что при использовании оператора
SELECTнельзя комбинировать вывод результатов и присвоение
переменных.
Если оператор SELECT возвращает несколько строк, то, при
использовании для записи значений переменных оператора SELECT, в
переменные будут записаны значения соответствующих столбцов первой
строки результирующего набора данных, остальные строки будут
потеряны.
Оператор SELECT, который в списке вывода содержит только
список имен столбцов таблиц БД или список переменных
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
предназначен для вывода результатов. Поэтому если мы хотим
вывести результат выполнения предыдущей команды присвоения
значений переменной @N на экран мы можем написать оператор
Select @N
Для того, чтобы вывести результаты выполнения арифметических
операторов также используется SELECT
Например:
SELECT 7%4, 4*7, ((45+18)/5.0) - 4, ((45+18)/5) - 4
--------- ---------- ---------------------- --------------------3
28
8.6000000
4
Арифметические операторы возвращают результат того же типа,
что и тип операндов.
В результате выполнения операций сравнения возвращается
логическое значение, но если сравнение невозможно возвращается
NULL – неопределенное значение. Операция сравнения невыполнима
– тогда, когда, либо сравниваются операнды разных типов, или когда
один из сравниваемых операндов имеет неопределенное значение.
Комментарии – являются одними из важнейших элементов языка.
Комментарии
позволяют
использовать
принцип
самодокументирования программного кода, а это облегчает
сопровождение и модификацию программ. В Transact SQL
комментарии бывают 2-х типов – однострочные и они оформляются
двумя последовательными дэфисами в строке.
--Текст комментария
Многострочный комментарий заключается в символы слэшзвездочка - звездочка слэш , например
/* Текст комментария строка 1
Комментарий строка 2 */
При написании кода на Transact SQL широко используются
встроенные функции. В общем случае этих функций много, но они
подразделяются на несколько разделов.
Таблица 3.
Функции по работе с датами (Date Functions)
Date function
DATEADD
DATEDIFF
Format
(datepart, number,
date)
(интервал,число,
дата)
(datepart, date1,
date2)
Описание
Добавляет дату
Возвращает разницу между
указанными частями дат dat1
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
DATENAME
(datepart, date)
DATEPART
(datepart, date)
GETDATE()
Day()
Month()
Year()
ISDATE(ex)
(date)
(date)
(date)
Полное
Year
Quarter
Month
Dayofyeaar
Day
Week
Hour
Minute
Second
Millisecond
и dat2 в заданном интервале
Возвращает строковое
представление заданной
части даты
Возвращает целочиленной
представление заданной
части даты
Возвращает текущую дату
Возвращает число
Возвращает месяц (число)
Возвращает число год
1 если символьная строка м.б.
переведена в datetime или
smalldatetime
Таблица 4.
Допустимые значения параметра интервал:
Сокращенное
Перевод
Yy или yyyy
Год
Qq или q
Квартал
Mm или m
Месяц
Dy или y
День года
Dd или d
День
Wk ww
Неделя
Hh
Час
Mi
Минута
Ss или s
Секунда
Ms
Миллисекунда
Таблица 5.
Математические функции (применимы только к числовым данным):
ABS
ACOS
ASIN
ATAN
ATN2
Абсолютная величина
Арккосинус
Арксинус
Арктангенс
Atan2(fload Возвращает угол в радианах, тангес
_expr,fload_ которого равен частному от деления
ex)
первого аргумента на второй с учетом
квадрата,задаваемого двумя
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
аргументами
CEILING
Ближайшее целое большее или равное
аргументу (округление вверх)
COS
Косинус угла
COT
Котангенс угла
DEGREES
Преобразование угла из радиан в
градусы
EXP
Экспонента
FLOOR(ex)
Возвращает ближайшее минимальное
целое (округление с отбрасыванием)
SIGN
Если положительное то 1, нулевое 0
Отрицательное –1
ISNUMERIC(
Проверяет тип выражения, если
ex)
числовой возвращает 1, в противном
случае
LOG
Логарифм по основанию
LOG10
Логарифм десятичный
PI
Число Пи
POWER
Power(x,y)
X в степени y
RADIANS
Переводит углы в радианы
RAND
Rand([seed] Генерирует случайное число в
)
диапазоне от 0 до 1, аргумент задает
начальное значение (начальную
установку генератора) Если аргумент не
используется, то начальное значение
генерируется на основе системного
времени
ROUND
Округление числа с заданной точностью
в кол-ве знаков после запятой
SIN
Синус
SQRT
Квадратный корень
TAN
Тангенс
Таблица 6.
Len
LTRIM
RTRIM
LEFT
RIGHT
LOWER
Символьные функции
Возвращает длину строки
Удаляет пробелы в начале строки
Удаляет пробелы в конце строки
Возвращает левую часть строки
Возвращает правую часть строки
В верхний регистр
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
UPPER
STR
SUBSTRING
CHARINDEX
PATINDEX
SPASE
REPLICATE
STUFF
Revers
QUOTENAME
Нижний регистр
Преобразует число в строку
Выделяет подстроку
Выполняет поиск подстроки
Выполняет поиск подстроки по шаблону
@a=Spase Возвращает указанное число пробелов
(10)
Заменяет все подстроки строки на
указанное значение
Select
Удаляет символы указанного фрагмента,
stuff(‘setre и заменяет их на другую подстроку
d’,3,5,’use’
)
----Seused
Переворачивает строку задом наперед
Конвертирует строку в UNICODE
Наиболее
часто
используемыми
являются
функции
преобразования.
К ним относятся функция сast и функция Convert.
CAST(expression as data_type) – используется для преобразования
из одного типа данных в другой тип данных. Функция CONVERT
используется для преобразования
в тип данных
datetime,
smalldatetime даных типа nchar,nvarchar,char,varchar
CONVERT (datatype[(length)], expression [, style])
Значение параметра стиль приведен в табл.7
Таблица 7.
Коды стилей при преобразовании даты.
Без века С веком
Стандарт
Формат отображения
(УУ)
(УУУУ)
0 или 100 по умолчанию
mon dd yyyy hh:miAM (или
PM)
1
101
USA
mm/dd/yy
2
102
ANSI
yy.mm.dd
3
103
English/French
Dd/mm/yy
4
104
German
dd.mm.yy
5
105
Italian
dd-mm-yy
6
106
Dd mon yy
7
107
Mon dd,yy
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
8
9
108
109
10
11
12
13
110
111
112
113
USA
Japan
ISO
Europa
Hh:mi:ss
mon dd yyyy hh:mi:sssAM
(илиPM)
mm-dd-yy
Yy/mm/dd
Yymmdd
dd mon yyyy
hh:mi:ss:mmm(24часа)
Например, для того, чтобы преобразовать переменную VarChar(10)
в тип данных Smalldatetime при использовании европейского типа
представления текущей даты надо использовать следующий формат:
Convert(varchar(10),@dd,104)
В табл. 8 приведены наиболее часто используемые системные
функции.
Таблица 8.
Системные функции.
Функция
Параметр(ы)
Возвращаемая информация
COALES (выражение1,
Возвращает первое выражение,
CE
выражение2,…,
которое не равно NULL
выражениеN)
ISNULL
(выражение,
Возвращает значение, если встретит
значение)
NULL (заменяет Null на значение)
NULLIF
(выражение1,
Возвращает NULL, когда выражение 1
выражение2)
равно NULL, а также когда выражение
1 и выражение 2 эквивалентны
SQL server контролирует ход работы всех пользователей. Сервер
передает с помощью глобальных переменных ряд значений, которые
приложения могут у себя использовать для корректировки хода
выполнения программы. Можно выделить следующие глобальные
переменные конфигурирования
 @@DBTS – текущее значение счетчика timestamp
 @@ROWCOUNT – возвращает количество строк которые были
обработаны последней командой SELECT
 @@ERROR - возвращает код последней ошибки в текущем
соединении
Управляющие операторы
Begin … End операторные скобки
Ключевые слова BEGIN и END применяются для обозначения набора
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
инструкций Transact SQL, который должен быть выполнен как один блок.
Синтаксис:
BEGIN
инструкции
END
Условная конструкция IF... ELSE
Ключевые слова IF и ELSE предназначены для контроля условного
выполнения инструкций внутри хранимой процедуры. Они дают
возможность проверять наличие определенного состояния и выполнять
инструкцию, являющуюся частью ветви IF, или инструкцию, являющуюся
частью ветви ELSE. Критерий проверки определяется выражением,
следующим за ключевым словом IF. Синтаксис инструкции IF ... ELSE:
IF логическое выражение
{ инструкция | блок инструкций }
[ ELSE { инструкция | блок инcтрукций } ]
В следующем примере инструкция PRINT применяется для вывода
сообщения, подтверждающего наличие в таблице базы данных строки,
соответствующей заранее заданным условиям. Если такой строки не
существует, выдается сообщение "Сведений нет". Так как ветвь ELSE в
данном примере не применяется, сообщение "Сведений нет" выводится
также и после сообщения о результатах проверки.
IF EXISTS (
SELECT * FROM Readers
WHERE Name_reader= 'Иванов И.А.’)
PRINT 'Сведения о таком читателе в Базе данных есть'
ELSE PRINT 'Сведений нет'
Оператор выбора
Синтаксис:
CASE expression
WHEN expression1 THEN exression1
[[WHEN expression2 THEN expression2[..]]
[ELSE expressionN]
END
CASE <вводимое выражение>
WHEN { <сравниваемое выражение> | < условное выражение> }
THEN <конечное выражение>
WHEN {<сравниваемое выражение> | < условное выражение> }
THEN <конечное выражение>
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
…
[ELSE <конечное выражение>….]
END
Пример:
DECLARE @v char(8)
Set @v = (select dol from prof where name = ‘Сидоров’)
Print CASE @v
When ‘acп’ THEN ‘аспирант’
When ‘ac’ THEN ‘ассистент’
When ‘доц’ Tnen ‘доцент’
When ‘проф’ THEN ‘профессор’
When ‘cт’ THEN ‘стажер’
When ‘cтуд’ THEN ‘студент’
ELSE ‘непонятно’
END
Можно использовать прямо в запросе
Select Category =
Case type
When ‘уч. пос’ THEN ‘учебное пособие’
When ‘мет.к л.р.’ THEN ‘методические указания к лабораторным
работам’
When ‘мет к кур.’ THEN ‘методические указания к курсовому
проекту’
END,
Title AS ‘Полное название’, AUTOR AS ‘Автор’
FROM BOOKS
Where YEAR_IZD > 1980
Циклы. Конструкция WHILE
Цикл WHILE применяется для выполнения одной или нескольких
инструкций TRANSACT SQL, при истинности заданного условия.
Инструкция, следующая за WHILE, выполняется циклически, пока
проверяемое условие истинно. Синтаксис инструкции WHILE:
WHILE логическое_выражение
<инструкция_SQL_1>
[BREAK]
<инструкцця SQL_2>
[CONTINUE]
 Если в цикл необходимо включить несколько инструкций,
используйте описанную выше конструкцию BEGIN ... END.
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
 BREAK - применяется внутри блока команд TRANSACT SQL,
находящихся внутри условной инструкции WHILE. Результатом
выполнения предложения BREAK будет переход к первому оператору,
следующему за концом блока цикла WHILE.
 CONTINUE – ключевое слово, после выполнения которого все
инструкции, следующие от него до инструкции, завершающий блок
цикла WHILE будут пропущены и управление будет передано на
начало цикла (первую инструкцию в блоке цикла).
DECLARE @I INT, @C INT, @N
SELECT @I = 1
SELECT @N =1
WHILE I=1
BEGIN /* начало внешнего блока */
SELECT @C= SELECT R1.COUNT_T
From R1
Where R1.Nun = @N
IF @C <> 0 Then
Begin
/* начало внутреннего блока */
Select
@N= @N+1
CONTINUE
End
/* конец внутреннего блока */
ELSE BREAK
END /* конец внешнего блока */
WHILE <условие>
{ < выполняемый оператор > | <блок операторов>}
[BREAK] – прервать цикл
[CONTINUE] – продолжить цикл
Оператор безусловного перехода GOTO
Допускается вставлять операторы безусловного перехода, хотя и
считается, что их использование является признаком плохого тона
программирования. Синтаксис:
GOTO метка
Метка – указывает, куда должно быть передано управление, метка –
идентификатор, который предшествует некоторому оператору и
отделяется от него двоеточием.
Пример:
DECLARE @A INT
SET @A=1
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
GOTO jump
SET @A=2
Jump: SELECT @A
Оператор WAITFOR
С помощью этого оператора можно приостановить выполнение
программы на некоторое время. Можно задать ожидание до некоего
определенного времени (по системному таймеру), или на некоторый
временной промежуток. Синтаксис оператора:
WAITFOR
{
DELAY
'время_продолжения_рботы' }
'время_задержки'
|
TIME
DELAY 'время_задержки' – указывает, что надо ждать указанное
количество времени. Максимум можно указать 24 часа.
TIME
'время_продолжения_рботы'
–
указывает,
что
нужно
приостановить работу и продолжить ее только тогда, когда по
систеному
таймеру
будет
время,
указанное
как
время_продолжения_рботы.
Пример:
PRINT
'Начало
работы;
Сейчас
'+CONVERT
(VARCHAR(20),GETDATE())
WAITFOR DELAY '00:00:10'
PRINT 'Продолжение после первой паузы на 10 сек. Сейчас' +
CONVERT (VARCHAR(20),GETDATE())
WAITFOR TIME '01:20'
PRINT 'Продолжение после второй паузы. Сейчас' +CONVERT
VARCHAR(20),GETDATE())
Курсоры.
Для работы с курсорами используются следующие операторы
(см.табл.9):
Таблица 9.
Операторы по работе с курсорами в Transact SQL
Оператор
DECLARE CURSOR
OPEN
Описание
Создает курсор
Открывает курсор
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
Выбирает данные
Закрывает ранее открытый курсор
Уничтожает ранее созданный
курсор
Оператор DECLARE CURSOR – определяет выполняемый
запрос, задает имя курсора и связывает результаты запроса с
заданным курсором. Этот оператор не является исполняемым для
запроса, он только определяет структуру будущего множества записей
и связывает ее с уникальным именем курсора. Этот оператор подобен
операторам описания данных в языках программирования.
Оператор OPEN – дает команду СУБД выполнить описанный
запрос, создать виртуальный набор строк, который соответствует
заданному запросу. Оператор OPEN
устанавливает указатель
записей (курсор) перед первой строкой виртуального набора строк
результата.
Оператор FETCH продвигает указатель записей на следующую
позицию в виртуальном наборе записей. В большинстве коммерческих
СУБД оператор перемещения FETCH реализует более широкие
функции перемещения, он позволяет перемещать указатель на
произвольную запись, вперед и назад, допускает как абсолютную
адресацию, так и относительную адресацию, позволяет установить
курсор на первую или последнюю запись виртуального набора.
Оператор CLOSE закрывает курсор и прекращает доступ к
виртуальному набору записей. Он фактически ликвидирует связь
между курсором и результатом выполнения базового запроса. Однако
в коммерческих СУБД оператор CLOSE не всегда означает
уничтожение виртуального набора записей. Мы коснемся этого далее.
Когда будем рассматривать работу с курсором в MS SQL Server 2000.
При использовании оператора CLOSE структура данных остается
доступной для повторного открытие.
Оператор DEALLOCATE - удаляет взаимосвязь между курсором
и именем курсора или переменной курсора. Если имя или переменная
являются последними, ссылающимися на курсор, все ресурсы,
выделенные курсору, освобождаются.
Курсор объявляется оператором DECLARE:
DECLARE <имя_курсора> CURSOR
[ LOCAL | GLOBAL ]
[ FORWARD_ONLY | SCROLL ]
[ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
[ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]
[ TYPE_WARNING ]
FETCH
CLOSE
DEALLOCATE
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
FOR <оператор выбора SELECT>
[ FOR UPDATE [ OF <имя_столбца 1> [ ,...n ] ] ]
Здесь
Опция LOCAL говорит о том, что курсор является локальным для того
блока (пакета, хранимой процедуры или триггера), в котором он
определен. По окончании работы этого блока курсор будет неявно
уничтожен.
Опция GLOBAL является противоположностью опции LOCAL. Она
говорит, что объявленный курсор продолжает существовать и по
окончании блока в котором он был создан, если только он не был
удален явно. По умолчанию используются установки сервера для
конкретной БД.
SCROLL - определяет, что допустимы любые режимы перемещения
по курсору (FIRST, LAST, PRIOR, NEXT, RELATIVE, ABSOLUTE) в
операторе FETCH. Если не указано ключевое слово SCROLL, то
считается доступной только стандартное перемещение вперед
спецификация NEXT в операторе FETCH.
FORWARD_ONLY – это опция являющаяся противоположностью
опции SCROLL, описанной выше и говорит что для перемещению
по курсору можно использовать только опцию NEXT команды
FETCH.
STATIC – определяет режим создания
набора строк,
соответствующего определяемому курсору, при
котором при
открытии курсора все данные, на которых он строятся копируются
во временную таблицу в БД tempdb. Таким образом,
все
изменения в исходных таблицах, произведенные после открытия
курсора другими пользователями, не видны в нем. Такой набор
данных нечувствителен ко всем изменениям, которые могут
проводиться другими пользователями в исходных таблицах, этот
тип курсора соответствует некоторому мгновенному слепку с БД.
Поскольку данные копируются во временную таблицу, такой курсор
не позволяет делать изменений в данных на которых он строится.
KEYSET - при использовании этой опции в момент открытия курсора
во временной таблице будет создан набор ключей набора строк,
получаемого при помощи оператора выбора SELECT. В
дальнейшем при перемещении по курсору будет происходить
перемещение по ключам из временной таблицы, а остальные поля
будут браться из исходных полей. Такой подход позволит лучше
отслеживать изменения, сделанные с момента открытия курсора.
Однако, это не позволит отследить все изменения.
DYNAMIC – при указании этой опции в курсоре будут отображаться
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
все изменения, сделанные с момента открытия курсора. При ее
использовании недоступна опция ABSOLUTE команды FETCH.
FAST_FORWARD – по сути обозначает совокупность опций
FORWARD_ONLY и READ_ONLY с добавлением оптимизации
производительности. Эта опция несовместима с опциями SCROLL,
FOR_UPDATE и FORWARD_ONLY.
READ ONLY - изменения и обновления исходных таблиц не будут
выполняться с использованием данного курсора. Курсор с данной
спецификацией может быть самым быстры в обработке.
SCROLL_LOCKS – гарантирует возможность удаления и изменений
строки на которую в данный момент указывает курсор. При
позиционировании на какую-либо строку при указании этой опции,
активная строка блокируется, и никто не сможет ничего с ней
сделать после того, как строка была прочитана в курсор и до того
момента как она будет освобождена (при переходе на другую
строку или закрытии курсора).
OPTIMISTIC – При указании этой опции, при чтении строки в курсор,
ее блокировка не производится.
TYPE_WARNING – при задании этой опции, пользователю могут быть
выданы специальные сообщения о некоторых нарушений.
FOR UPDATE [OF <имя столбца 1> [,...<имя столбца n>]] мы задаем
перечень столбцов, в которых допустимы изменения в процессе
нашей работы с курсором. Такое ограничение упростит и ускорит
работу СУБД.
Пример:
Опишем курсор, который содержит список должников нашей
библиотеки. Мы не собираемся использовать данный курсор для
удаления или обновления строк. Поэтому мы его определили как
курсор только для чтения.
declare Deptor Cursor Local for
select distinct NUM_reader from exemplar
Where Yes_NO ='0' and Data_RETURN < Getdate()
FOR READ ONLY
Оператор открытия курсора имеет следующий синтаксис
OPEN {{[ GLOBAL ] <имя_курсора> } | | <имя переменной типа курсор>
}
Именно оператор открытия курсора инициирует выполнение
базового запроса, соответствующего описанию курсора, заданному в
операторе DECLARE … CURSOR.
SQL Server возвращает код завершения операции в специальной
системной переменной @@Error. При неудачном выполнении
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
операции открытия курсора СУБД возвращает ненулевое значение
@@Error.
После того, как курсор открыт, в системной переменной
@@Cursor_Rows будет содержаться количество строк в открытом
курсоре.
После открытия указатель текущей строки установлен перед
первой строкой курсора. Стандартно оператор FETCH перемешает
указатель текущей строки на следующую строку и присваивает
базовым переменным значение столбцов, соответствующее текущей
строке.
Оператор FETCH имеет следующий синтаксис:
FETCH
[NEXT | PRIOR | FIRST | LAST | ABSOLUTE {n | <имя_переменной>} |
RELATIVE{n|<имя_переменной>}]
FROM { { [ GLOBAL ] <имя курсора> } | <имя переменно типа курсор> }
INTO <список базовых переменных>
Здесь параметр NEXT задает выбор следующей строки после
текущей из базового набора строк, связанного с курсором. Параметр
PRIOR задает перемещение на предыдущую строку по отношению к
текущей. Параметр FIRST задает перемещение на первую строку
набора, а параметр LAST задает перемещение на последнюю строку
набора, ABSOLUTE, задает номер конкретной строки, параметр
RELATIVE задает относительный адрес. При абсолютной адресации
отрицательное число будет трактоваться как n-ая строка от конца
набора данных; в случае же 0 в качестве параметра, данные вообще
не будут возвращены. При относительной адресации положительное
число сдвигает указатель в низ от текущей записи, отрицательное
число сдвигает вверх от текущей записи. В случае, если число
отрицательное или 0 при первом вызове, то никаких данных
возвращено не будет.
После каждого выполнения оператора FETCH изменятся
состояние системной переменной @@Fetch_status. Эта переменная
показывает результат работы оператора. Переменная может иметь
три состояния (см. таб.10):
Таблица 10.
.
Значение глобальной переменной @@Fetch_status при работе с
курсором
Значение
Описание
переменной
0
Оператор выполнен успешно. В переменные
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
занесены значения из очередной строки набора
данных
-1
Строки в наборе данных закончились или же
затребованная строка находится вне его пределов,
либо же произошла ошибка при выполнении
оператора
-2
Строки в наборе данных нет. Это значение может
получиться в том случае, когда определена опция
KEYSET курсора. В этом случае при открытии во
временную таблицу копируются ключи набора
данных, а все остальные значения получаются
путем обращения к реальным таблицам по
известным ключам при выполнении Fetch. Если
после открытия курсора строка, вошедшая в набор
(ключ ее скопирован во временную таблицу) была
удалена, либо же ее ключ изменен, то найти строку
по заданному ключу будет невозможно. В этом
случае будет выдан код -2 в переменную
@@Fetch_status
Следует помнить, что переменная @@Fetch_Cursor –
глобальная, т.е. если существует несколько вложенных курсоров, то
значение @@Fetch_Cursor будет относиться к тому из них, для кого
выполнен оператор FETCH.
Оператор закрытия курсора
Оператор закрытия курсора имеет простой синтаксис, он
выглядит следующим образом:
CLOSE {{[ GLOBAL ] <имя_курсора> } | | <имя переменно типа курсор>
}
Оператор закрытия курсора освобождает память, используемую
под данные набора данных курсора и снимает наложенные на данные
блокировки. При этом сама структура курсора, т.е. его описание
остается доступным. Т.е. можно вновь открыть курсор без того, чтобы
его вновь описывать.
Оператор уничтожения курсора
Наряду с оператором закрытия курсора используется оператор
его уничтожения:
DEALLOCATE {{[ GLOBAL ] <имя_курсора> } | | <имя переменно типа
курсор> }
При выполнении оператора DEALLOCATE
SQL Server
освобождает разделяемую память, используемую командой описания
МЕЖДУНАРОДНЫЙ БАНКОВСКИЙ ИНСТИТУТ
INTERNATIONAL BANKING INSTITUTE
курсора DECLARE. После выполнения этой команды невозможно
выполнение команды OPEN для данного курсора.
Задание 1.
В учебной БД «Библиотека» создать глобальный курсор, который
будет содержать список названий всех книг, которые имеются в
библиотеке. Открыть курсор и при перемещении по нему каждый раз
считать и выводить на экран общее количество экземпляров данной
книги в библиотеке и количество свободных экземпляров книги в
данный момент. При выполнении задания помним, что переменная
@@fetch_status появляется только после того, как Вы выполнили хотя
бы одну операцию Fetch для курсора. Количество экземпляров книг
все и тех, что на руках Вы можете сосчитать стандартными SQLзапросами, а данные поместить в локальные переменные. Не
забудьте закрыть курсор и уничтожить его.
Задание 2.
Добавьте столбец «Cost» - стоимость книги в таблицу «Books» и
заполните его для всех книг.
Создайте курсор, который выводит список читателей.
Перемещаясь по курсору выведите для каждого читателя количество
книг, находящихся на руках с указанием общей их стоимости.
Download