Статические и динамические курсоры
Поможем в ✍️ написании учебной работы
Поможем с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой

Курсоры могут быть статическими и динамическими.

При объявлении статического курсора должен указываться атрибут STATIC. Открытие статического курсора приводит к выгрузке результирующего набора строк в динамически созданную временную таблицу системной БД TEMPDB, и все дальнейшие курсорные операции осуществляются с этой таблицей. После открытия курсора изменения в исходных таблицах, которые осуществляются в рамках этого или других сеансов, не будут отражаться в курсорном результирующем наборе.

Рис. 13.31–13.33 демонстрируют особенности работы со статическим курсором.

 

Рис. 13.31. Результирующий набор SELECT-запроса, выполненного
до исполнения сценария на рис. 13.32

На рис. 13.31 представлен результат SELECT-запроса, отражающий содержимое результирующего набора, который будет сформирован в сценарии на рис. 13.32 при открытии курсора с именем C_ TEACHER.

В сценарии на рис. 13.32 объявлен и затем отрыт курсор C_ TEACHER. При этом сформированный результирующий набор (он будет идентичен набору, представленному на рис. 13.31) выгружается во временную таблицу системной БД TEMPDB. Заметьте: все изменения (операторы UPDATE, DELETE и INSERT ограничеы с сверху и снизу линиями комментарий), выполненные в исходной таблице TEACHER, никак не отразились на результате выборки строк курсора с помощью оператора FETCH. В то же время, если снова выполнить SELECT-запрос, аналогичный представленному на рис. 13.31 и курсорному запросу, то получим ожидаемый результат, отражающий изменения в таблице TEACHER (рис. 13.3).

 

 

Рис. 13.32. Пример, демонстрирующий особенности работы статического курсора

 

Рис. 13.33. Результирующий набор SELECT-запроса,
выполненного после исполнения сценария на рис. 13.32

 

Обратите внимание на применение в сценарии на рис. 13.2 системной функции @@ CURSOR_ ROWS, с помощью которой можно получить количество строк в результирующем наборе статического курсора.

Вернем таблицу TEACHER в состояние, предшествующее выполнению сценария на рис. 13.32 и соответствующее запросу на рис. 13.31. После этого выполним сценарий, представленный на рис. 13.34, в котором применяется динамический курсор.

 

Рис. 13.34. Пример, демонстрирующий особенности работы
 динамического курсора

 

Заметим: изменение, выполненное оператором UPDATE, отразилось в результирующем наборе; удаленной (DELETE) строке соответствует строка со значением NULL во всех столбцах, а добавленная (INSERT) в исходную таблицу строка в курсорный результирующий набор не введена.

Обратите внимание: значение функции @@ CURSOR_ ROWS после открытия динамического курсора всегда равно –1.

Следует отметить, что кроме STATIC и DYNAMIC-курсоров допускается использовать курсоры с атрибутом KEYSET, занимающие промежуточное положение между STATIC и DYNAMIC. Для знакомства с KEYSET- курсорами рекомендуется изучить пособие [5].

13.15.4. Курсоры с атрибутами FORWARD_ ONLY и SCROLL

По умолчанию для курсора установлен атрибут SCROLL, позволяющий применять оператор FETCH с дополнительными опциями позиционирования.

Для демонстрации возможностей позиционирования в SCROLL- курсорах предварительно рассмотрим запрос на рис. 13.35, применяющий функцию ROW_NUMBER.

 

Рис. 13.35. Применение оконной функции ROW_NUMBER
для сортировки нумерации строк

 

Функция ROW_NUMBER предназначена для нумерации строк результирующего набора и относится к классу оконных встроенных функций T-SQL. Основным признаком того, что применяется оконная функция, является ключевое слово OVER, за которым в скобках следуют опции, разбивающие результирующий набор на подмножества (окна) строк, а также сортирующие эти строки внутри подмножества. В приведенном примере разбиение не осуществляется, поэтому все строки результирующего набора только сортируются. Результатом выполнения функции является номер строки в результирующем наборе. Более подробно с оконными функциями можно ознакомиться в пособии [5].

 

Рис. 13.36. Пример, демонстрирующий опции позиционирования
оператора FETCH, доступные в SCROLL-курсорах

 

Курсоры с атрибутом FORWARD_ONLY допускают чтение строк результирующего набора только в одном порядке – сверху вниз (FETCH NEXT).

13.15.5. Курсоры с атрибутами FOR UPDATE и READ_ ONLY

Курсор дает возможность программисту последовательно обрабатывать строки результирующего набора строк, полученного в результате выполнения связанного с курсором SELECT-запроса.

Для курсоров с установленным свойством FOR UPDATE, помимо чтения данных из строк с помощью оператора FETCH, можно эти строки изменять или удалять с помощью специального формата операторов UPDATE и DELETE.

На рис. 13.37–13.38 представлен пример использования курсора со свойством FOR UPDATE.

 

Рис. 13.37. Результирующий набор SELECT-запроса, выполненного

до запуска сценария на рис. 13.38

 

Обратите внимание: при объявлении курсора C_ TEACHER (рис. 13.38) используется ключевая фраза FOR UPDATE, дающая возможность применять операторы DELETE и UPDATE для удаления или изменения строки таблицы.

В секции WHERE операторы DELETE и UPDATE (рис. 13.38) используют операцию CURRENT OF, для которой указывается имя курсора (в примере C_ TEACHER). Такой формат операторов позволяет удалять или изменять строки в таблице (TEACHER), соответствующие текущей позиции курсора в результирующем наборе.

 

Рис. 13.38. Сценарий, демонстрирующий применение курсора
 со свойством FOR UPDATE

 

Свойством FOR UPDATE могут обладать только динамические (обладают по умолчанию) и ключевые (в пособии не рассматриваются) курсоры.

Курсору может быть установлено свойство READ_ONLY, запрещающее применение операции CURRENT OF в секции WHERE операторов DELETE и UPDATE. Однако свойство READ_ONLY не мешает применять эти операторы без использования CURRENT OF (рис. 13.39).

 

Рис. 13.39. Сценарий, демонстрирующий применение курсора
со свойством READ_ONLY

 

В сценарии на рис. 13.39 при объявлении курсора C_ TEACHER используется ключевое слово READ_ONLY. Для удаления и изменения строк таблицы TEACHER применяются операторы DELETE и UPDATE, не применяющие операцию CURRENT OF в секции WHERE.

Следует отметить, что атрибут READ_ONLY имеет смысл только для динамических и ключевых курсоров, статические курсоры по определению применяются только для чтения.

 








Применение транзакций

Состояние БД называют согласованным, если хранящиеся данные удовлетворяют всем ограничениям целостности и не противоречат друг другу. Первая часть определения очевидна, вторая требует пояснения. Приведем пример.

Рассмотрим БД банковской системы, учитывающей операции на текущем счете клиента в таблице Текущий счет, а кассовые операции (выдача и прием наличных денежных средств) – в таблице Касса (рис. 13.40).

Рис. 13.40. Схема выполнения операции «Выдача наличных»

 

Если клиент банка получает 50 единиц денежных средств со своего текущего счета в виде наличности, то этому событию в гипотетической банковской системе будет соответствовать банковская операция «Выдача наличных», которая в БД представляется в виде результата выполнения двух операторов INSERT, добавляющих по строке в таблицы Текущий счет и Касса. Добавленная строка в таблицу Текущий счет будет отражать тот факт, что обязательства банка перед клиентом теперь уменьшатся на 50 единиц (уменьшился остаток на текущем счете), а строка в таблице Касса – факт уменьшения наличных денег в кассе банка на те же 50 единиц. Если два оператора INSERT выполнились успешно, то БД перешла из одного согласованного состояния в другое, тоже согласованное.

Предположим теперь, что после успешного выполнения первого оператора INSERT, добавившего строку в таблицу Текущий счет, произошел системный сбой, не позволивший выполнить второй оператор INSERT и, соответственно, клиенту получить причитающиеся ему наличные денежные средства. Произойдет рассогласование, которое заключается в том, что обязательства банка перед клиентом уменьшились, а кассовый остаток остался прежним – клиент не получил наличные. В этом случае БД перешла из согласованного состояния в несогласованное.

Как видно из приведенного примера, понятие «согласованное состояние БД» зависит от той предметной области, состояние которой отражается в БД. Очевидно, что если бы рассматривалась БД, хранящая, например, данные о ходе технологического процесса, то согласованность бы понималась иначе.

С другой стороны, рассогласование в любом случае будет происходить в тогда, когда при необходимости одновременно выполнить несколько изменений в БД, выполняется только их часть, а другая часть не выполнится вообще. Тогда, по всей видимости, если бы был механизм, позволяющий объединять несколько операторов изменения БД в одну атомарную операцию, которая либо полностью выполнялась, либо полностью не выполнялась, то эта проблемы была бы решена.

В первом приближении транзакцией будем назвать механизм БД, позволяющий объединять несколько операторов, изменяющих БД таким образом, чтобы при выполнении этой совокупности операторов они или все выполнились, или все не выполнились.

Дата: 2019-02-25, просмотров: 283.