Постоянно хранимые модули
Что в имени твоем?
Название дополнения SQL – постоянно хранимые модули (persistent stored modules) – очень метко описывает их назначение.
Да вы уже и сами могли догадаться. Если слово модуль вам неизвестно, освежите в памяти материал главы 15. По логике хранимый модуль должен являться чем-то таким, что находится в некотором месте до тех пор, пока не потребуется. Кроме того, постоянно хранимый модуль должен быть чем-то, что находится под рукой в течение определенного периода времени. Вот, собственно, и все, о чем рассказывается в этой главе.
Вы почти угадали, хотя логика немного увела вас в сторону. В этой главе описываются подобные модули. Но постоянно хранимые модули больше связаны с другими возможностями SQL. В SQL:2003 огромное количество постоянно хранимых модулей содержат необходимые функции, которые следовало включить еще в SQL-92, но этого не произошло. Такие функции значительно повышают мощность и полезность SQL, и они должны были где-то находиться. Некоторые из них действительно хранятся под своими именами (в частности, хранимые функции и хранимые процедуры). Ладно, довольно логики. Важно лишь, что эти новые средства существуют и работают.
Что если операции вставки в таблицы Students (студенты) и Roster (расписание) произошли, а в результате вмешательства постороннего пользователя операция вставки в таблицу Receivable (плата за учебу) не выполнилась. Получится, что студент будет зачислен, но счет за обучение ему выписан не будет. Такие ошибки могут слишком дорого обойтись университету. Для предотвращения развития событий по данному сценарию необходимо ввести концепцию атомарности. Атомарная команда является неделимой. Она либо выполняется целиком, либо не выполняется вовсе. Простые команды SQL атомарны по своей природе. Другое дело – составные команды SQL. Однако и составную команду тоже можно определить атомарной. В приведенном ниже примере составная команда SQL становится безопасной благодаря введению атомарности.
void main { EXEC SQL BEGIN ATOMIC INSERT INTO students (StudentID, Fname, Lname) VALUES (:sid,:sfname,:sid); INSERT INTO roster (ClassID, Class, StudentID) VALUES (:cid,:cname,:sid); INSERT INTO receivable (StudentID, Class, Fee) VALUES (:sid,:cname,:cfee); END; /* Проверка значения SQLSTATE на код ошибки */ }
Ключевые слова ATOMIC после BEGIN гарантируют выполнение всей команды полностью, а в случае возникновения ошибки происходит откат к исходному состоянию базы данных.
Переменные
Все высокоуровневые языки программирования, такие как С или Basic, позволяют использовать переменные. До появления SQL/PSM переменные в SQL использовать было нельзя. Переменные являются символическими именами значений определенного типа. В составных командах можно объявить переменную и определить ее значение. В ходе выполнения составной команды переменная может использоваться. После завершения выполнения составной команды все переменные, объявленные в ней, уничтожаются. Таким образом, переменные в SQL являются локальными переменными составной команды, в которой они объявлены. Рассмотрим следующий пример:
BEGIN DECLARE prezpay NUMERIC; SELECT salary INTO prezpay FROM EMPLOYEE WHERE jobtitle= 'president'; END;
Курсоры
В составных командах можно использовать курсоры. Как уже упоминалось в главе 18, курсоры используются для построчной обработки данных. В составной команде можно объявить курсор, использовать его, а затем забыть о нем, так как курсор уничтожается сразу после завершения выполнения составной команды. Ниже приведен пример использования курсора.
BEGIN DECLARE ipocandidate CHARACTER (30); DECLARE cursorl CURSOR FOR SELECT company FROM biotech; OPEN cursor1; FETCH cursor1 INTO ipocandidate; CLOSE cursor1; END;