Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Программирование приложений баз данных с использованием СУБД MS SQL Server. Учебное пособие
.pdf
В блоке BEGIN TRY... END TRY выполняются потенциально
опасные команды, если при этом произойдет ошибка уровня 11–19,
то выполнение будет передано в блок CATCH.
Уровни ошибок:
1–10. Информационные сообщения. Например, обнаружение NULL-значений при выполнении агрегатных функций. Так как
управление в блок CATCH данные ошибки не передают, то для получения информации
об ошибке можно использовать функцию
@@ERROR;
11–19. Относительно серьезные ошибки. Например, нару-
шение ограничений внешнего ключа;
20–25. Очень серьезные ошибки. Это ошибки на уровне системы, поэтому в коде нельзя узнать об их возникновении. Такие
ошибки разрывают текущее соединение и прерывают выполнение
команд.
3.4.9. Комментарии
Существует два вида комментариев:
однострочные – в этом случае игнорируется текст справа от
символов комментария: -- (двойной дефис);
многострочные – игнорируется текст, записанный между
двумя парами символов: /* … */.
3.4.10. Функции Transact-SQL
MS SQL Server имеет ряд встроенных функций для облегчения и ускорения обработки данных.
30

Математические функции
Большинство математических функций возвращают результат
того же типа, что и исходные значения. Например, при переводе
величины угла из градусов в радианы в случае Radians (90) результат равен 1, что неверно, так как в качестве аргумента функции использовано целое число. Правильная запись: Radians (90.0).
Abs (выражение) – вычисление абсолютного значения выражения. Можно использовать
как целочисленные, так и нецелочис-
ленные величины.
IsNumeric (выражение) – проверка, имеет ли указанное выражение числовой тип данных. Результат равен 1, если выражение
имеет числовой тип, иначе – 0.
Rand () – возвращает случайное значение на основе системного времени в диапазоне от 0 до 1.
Floor (выражение) – округление указанного значения до ближайшего минимального целого числа.
Ceiling (выражение) – возвращает
ближайшее целое число,
большее или равное данному.
Power (выражение, степень) – возведение в степень выражения. Тип возвращаемого значения совпадает с исходным типом.
Sqrt (выражение) – вычисляет квадратный корень.
Строковые функции
Ascii (строка) – возвращает ASCII-код самого левого символа
строки.
Char (выражение) – возвращает символ, ASCII-код которого
соответствует указанному числовому выражению.
Len (строка) – вычисляет длину строки в
символах.
LTrim (строка), RTrim (строка) – удаляют начальные и конце-
вые пробелы соответственно.
Left (строка, число), Right (строка, число) – возвращают ука-
занное количество символов строки, начиная с левого и правого
края строки соответственно.
SubString (строка, начало, длина) – возвращает для строки
подстроку указанной длины, начиная с указанного символа.
CharIndex (строка 1, строка 2 [, старт]) – поиск подстроки
строка 1 в
строке строка 2. Возвращает порядковый номер первого
символа, с которого начинается первое вхождение подстроки
31

в строку. Дополнительно можно указать стартовую позицию, с которой будет начат поиск.
Stuff (строка 1, начало, длина, строка 2) – удаляет определен-
ное количество символов строки 1, начиная с указанного, и заме-
няет их новой строкой 2.
Replace (строка 1, строка 2, строка 3) – заменяет все вхожде-
ния строки строка 2 в исходной строке строка 1 на строка 3.
Reverse (строка) – возвращает строку, символы которой запи-
саны в обратном порядке по отношению к исходной строке.
Функции для работы с датами
GetDate () – возвращает текущее системное время.
IsDate (выражение) – проверяет правильность выражения на
соответствие одному из возможных форматов ввода даты.
Day (дата), Month (дата), Year (дата) – возвращают день, месяц
и год из указанной даты.
DateName (тип,
дата) – выделяет из даты указанную в типе
часть и возвращает ее в символьном формате. Формат частей:
yy или yyyy – год, qq или q – квартал, mm или m – месяц, dd или
d – день, wk или ww – неделя, hh – час, mi или m – минута, ss или
s – секунда, ms – миллисекунда.
DatePart (тип, дата) – выделяет из даты указанную часть и воз-
вращает ее в числовом формате.
DateAdd (тип, число,
дата) – добавляет к указанной дате чис-
ло, тип которого указан в первом параметре.
DateDiff (тип, начало, окончание) – возвращает разницу меж-
ду указанными частями дат в указанном типе.
Конфигурационные функции
Возвращают информацию о текущей конфигурации MS SQL
Server. Например:
@@Version – возвращает информацию о дате, версии и типе
процессора сервера.
@@ServerName – символьное имя локального MS SQL Server.
@@Max_Connections – максимально разрешенное
количество
одновременных подключений к серверу.
32

Системные функции
Возвращают информацию о значениях, объектах и текущих
параметрах MS SQL Server.
DataLength (выражение) – возвращает число, соответствующее
количеству байт, необходимых для хранения результата выражения.
@@Error – код последней ошибки, произошедшей в текущем
соединении. Если ошибок нет, результат равен 0.
@@RowCount – количество записей, обработанных последней
выполненной командой TransactSQL.
Host_Name() – символьное имя компьютера в сети, на котором
выполняется команда
.
System_User и Session_User – возвращают соответственно имя
учетной записи пользователя для входа и имя пользователя текущей базы данных.
@@IDLE – определяет количество миллисекунд, прошедшее
со времени последнего запуска MS SQL Server.
NewID() – генерирует новое значение типа
UniqueIdentifier(GUID).
3.4.11. Отладка кода в Management Studio
В MS SQL Server 2008 появилась возможность отлаживать
SQL-код при помощи пошагового выполнения. Для этого сущест-
вуют команды Debug – Step Into (F11) и Debug – Step Over (F10).
Команда Debug – Toggle Breakpoint (F9) устанавливает точку останова, до которой будет происходить выполнение кода.
Во время отладки доступны такие окна:
Locals – автоматически содержит список всех локальных
переменных и показывает их текущие значения;
Watch – позволяет вручную добавлять переменные
для от-
слеживания их значений;
Call stack – показывает стек вызовов функций.
33

4. ПОДДЕРЖКА ТРАНЗАКЦИЙ
4.1. Определение
Транзакции – механизм, обеспечивающий совместную работу
различных пользователей с общими данными. Транзакция представляет собой одну или несколько команд Transact-SQL, обрабатываемых, как единое целое. SQL Server гарантирует, что данные,
к которым обращается транзакция, останутся неизменными на всем
протяжении существования транзакции. По умолчанию, каждая
команда Transact-SQL рассматривается как отдельная транзакция.
В обычном режиме ни одна команда
изменения данных не может
быть выполнена вне транзакции. Существуют определенные требования к выполнению транзакций системой управления базами данных:
Атомарность. Все изменения, выполненные в транзакции,
рассматриваются как единый блок. При нормальном завершении
блока изменение данных фиксируется, в противном случае данные
должны быть восстановлены в состоянии, в котором они были
до начала транзакции.
Согласованность. После завершения транзакции все данные
должны находиться в корректном состоянии и не нарушать ограничений целостности, определенных в базе данных.
Изолированность. Все транзакции должны работать незави-
симо друг от друга, т. е. быть изолированными. Если транзакция
использует данные, изменяемые другой транзакцией, то она будет
видеть
их в состоянии, в котором они находились либо до начала
транзакции, либо после ее окончания.
Устойчивость. После того как транзакция выполнит все не-
обходимые изменения, система производит фиксирование транзакции, после чего система не может быть возвращена в состояние,
в котором она была до начала транзакции.
4.2. Блокировки
Блокировкой называется временное ограничение, накладываемое на использование тех или иных ресурсов. Блокировки используются для обеспечения изолированности транзакций. Если
транзакция меняет данные, то необходимо их полностью блокиро-
34

вать. Это гарантирует, что другие транзакции не будут использовать еще не зафиксированные данные, которые в окончательном
виде могут иметь совсем другие значения. В большинстве же случаев часто бывает достаточно просто запретить изменение данных,
оставив возможность чтения.
При отсутствии механизма блокировок возможны следующие
проблемы:
Потерянные обновления (Lost updates). Если две транзак
-
ции одновременно извлекают информацию на основе определенного критерия, а затем обновляют ее, то возможно перезаписывание
второй транзакцией данных, уже измененных первой транзакцией.
Черновое чтение (Dirty reads). Чтение одной транзакцией
данных, изменяемых в это же время другой транзакцией. Поскольку возможен откат второй транзакции, то считанные первой транзакцией данные могут
оказаться некорректными.
Неповторимое чтение (Unrepeatable reads). Эта проблема
связана с многократным чтением транзакцией одних и тех же данных. Между операциями чтения другая транзакция может изменить
данные и повторное сканирование даст другие результаты.
Проблема чтения фантомов (The phantom read problem).
Эта проблема возникает, когда во время выполнения транзакции
в таблицу вставляются новые строки или удаляются
строки. В результате при очередном сканировании может быть обработан совсем иной набор данных.
Данные проблемы решаются с помощью блокировок следую-
щих типов:
Разделяемые блокировки (Shared lock). Данные, на кото-
рые наложены разделяемые блокировки, могут быть прочитаны
любой транзакцией, но ни одна транзакция не может вносить в них
изменения. Разделяемую
блокировку можно создать в том случае,
если на данные не наложена эксклюзивная блокировка.
Эксклюзивные блокировки (Exclusive lock). Полностью
запрещается доступ к данным со стороны других транзакций. Чтобы создать эту блокировку, необходимо отсутствие каких-либо
блокировок на эти данные.
Блокировки обновления (Update lock). Создаются для пре-
дотвращения взаимоблокировок, которые могут возникнуть, если
транзакции наложили разделяемые блокировки на считываемые
две
35

данные, а затем захотели их изменить и на время изменения поменять разделяемую блокировку на эксклюзивную. Если необходимо
читать данные, а затем произвести изменения, то можно создать
блокировку обновления, которая существует только одна. Только
одна транзакция может поменять блокировку обновления на эксклюзивную блокировку для изменения данных.
В большинстве современных СУБД
реализованы механизмы
блокирования, решающие рассмотренные выше проблемы, возникающие при одновременной работе нескольких транзакций с одними и теми же данными.
4.3. Использование транзакций
Если транзакция работает с таблицами только одной базы данных, то она называется стандартной, если с таблицами нескольких
баз данных – распределенной. Выполнение транзакции происходит
на стороне
клиента (соединения) или сервера. В первом случае момент начала и окончания транзакции определяет сам пользователь.
Если транзакция находится в хранимой процедуре, то контроль начала транзакции и ее завершения организует сервер. В SQL Server
имеется несколько способов определения транзакции:
Автоматический. SQL Server автоматически начинает вы-
полнение транзакции для каждой новой команды. В
случае успешного выполнения команды происходит фиксирование транзакции,
если команда закончилась безуспешно, то происходит откат транзакции.
Явный. В этом случае пользователь должен четко указать
начало и конец транзакции. Начало указывается при помощи оператора BEGINTRAN [имя_транзакции]. Откат транзакции осуществляется при помощи команды ROLLBACKTRAN [имя_транзакции].
Завершение транзакции и фиксирование
результатов ее работы происходит по команде COMMITTRAN [имя_транзакции]. Если
при создании транзакции было указано ее имя, то его надо указать
в этой команде, чтобы система знала, какую транзакцию необходимо фиксировать.
Неявный. В режиме неявного начала транзакций система
автоматически начинает новую транзакцию, как только закончилась предыдущая. Пользователь
не должен указывать начало тран-
36

закции командой BEGINTRAN, так как за него это делает система.
Однако пользователь должен явно выполнить фиксирование или
откат транзакции с помощью команд COMMITTRAN или
ROLLBACKTRAN.
В качестве примера создадим транзакцию, осуществляющую
выдачу экземпляра книги читателю в базе данных BookLibrary. При
выдаче книги необходимо добавить новую запись в таблицу
History, хранящую протокол выданных экземпляров книг, и
устано-
вить флажок IsFree в 0 в таблице Items для выдаваемого экземпляра. Текст программы приведен ниже.
declare @argItem int,@count int,@FBIT, @argNB int
set @argItem=10000081
set @argNB = 100001
select @F=isfree from Items where id=@argItem
if @F=1
begin
begin tran
insert into History (IdItem ,Dat0 ,NB) values(@argItem
,GETDATE(),@argNB)
if @@ROWCOUNT =0
begin
print 'Ошибка'
rollbacktran
end
else
begin
update Items set isfree = 0 where id=@argItem
if @@ROWCOUNT =0
begin
print 'Ошибка'
rollback tran
end
else
commit tran
print 'Все нормально'
end
end
else
print 'Ошибка'
37

Здесь идентификатор выдаваемого экземпляра и номер читательского билета задаются в переменных @argItem и argNB. В начале проверяется наличие экземпляра, а также его наличие в библиотеке. Затем инициируется транзакция, в ходе которой добавляется новая запись в таблице HISTORYи изменяется значение
столбца IsFree в таблице Items. Успешность обоих действий контролируется при помощи
системной переменной @@RowCount –
количества записей, обработанных последней командой. Если ее
значение равно 0, то происходит откат транзакции.
38

5. ПРОГРАММИРУЕМЫЕ ОБЪЕКТЫ БАЗЫ ДАННЫХ
5.1. Хранимые процедуры
Хранимые процедуры – это именованный набор операторов
Transact-SQL, хранящийся на сервере. Зная имя, пользователи мо-
гут вызвать процедуру, запуская тем самым на выполнение весь набор команд, представляющих тело процедуры. Почти любая команда Transact-SQL может быть включена в процедуру, что делает
возможным выполнение повторяющихся задач в пользовательских
приложениях и администрировании.
При первом
обращении к хранимой процедуре сервер генерирует и сохраняет в кэше процедур планы компиляции и выполнения
процедуры, которые используются последующими выполнениями.
Кэш процедур – это пространство памяти, содержащее план выполнения всех выполняемых сейчас операторов Transact-SQL. Размер
кэша изменяется, динамически соответствуя необходимому уровню. Если в кэше есть план выполнения, то процедура выполняется
быстрее, за счет того что серверу не нужно разбирать запрос и вырабатывать необходимые действия для решения поставленной задачи. Это дает некоторый выигрыш в производительности. Кроме
того, хранимая процедура выполняется не на клиентском, а на серверном компьютере, что позволяет реализовать логику обработки
данных на сервере. Тем самым снижается
загрузка клиентских
компьютеров и сети, поскольку клиенту по сети передается только
результат запроса
, а не все промежуточные наборы данных, обра-
зующиеся при его выполнении. Главным же назначением хранимых
процедур является создание защитного слоя и прикладного интерфейса для пользовательских баз данных, которые отделяют приложения от изменений в структуре хранимых данных. Если процедуры поддерживают все бизнес-функции, которые нужны для выполнения пользователю
, пользователь никогда не нуждается в прямом
доступе к таблицам. Все можно делать через процедуры, которые
могут выступать дополнительным гарантом целостности данных
и безопасности базы данных. Пользователи могут получать право
выполнять процедуры, даже если у них нет права на использование
39
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
