Выполнение однострочных и многострочных запросов с помощью внедренных операторов SQL и курсоров

Внедрение операторов SQL в прикладные программы

Язык SQL как специальный язык не имеет многих средств, присущих универсальным языкам высокого уровня (С++, Delphi, Visual Basic и др.), например таких, как команды управления хо­дом выполнения программы IF...THEN...ELSE, GO TO или DO WHELE.

Для устранения этого недостатка стандартом ISO/EC 9075:2003 предусматривается возможность внедрения операторов в клиент­ские приложения, разрабатываемые на языках высокого уровня, которые называют базовыми языками. В этом случае практически все операторы SQL однозначно выполняют свои задачи, кроме оператора SELECT.

На практике существует два способа использования операто­ров SQL в программах базового языка: внедрение операторов и применение программного интерфейса.

Внедрение операторов SQL. При использовании данного спосо­ба отдельные операторы SQL внедряются непосредственно в текст исходной программы и чередуются с операторами базового язы­ка, что позволяет создавать приложения, которые могут непос­редственно обращаться к таблицам базы данных и работать с ними. В этом случае специальные программы — предкомпиляторы — пре­образуют текст исходной программы, производя замену операто­ров SQL соответствующими вызовами процедур СУБД, после чего этот текст компилируется. Стандарт ISO/EC 9075:2003 предусмат­ривает обязательную поддержку внедренных операторов SQL для языков программирования ADA, С, COBOL, Fortran, Pascal, PL/1.

Применение программного интерфейса — API. Данный способ использования операторов SQL состоит в том, что программисту предоставляется возможность с помощью API обращаться к стан­дартному набору функций из создаваемых им программ.

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

Соответствующие API имеются в СУБД Oracle. В СУБД Access предлагается программный интерфейс ADO, представляющий собой надстройку над интерфейсом ODBC.

Внедренные операторы подразделяют на статические и дина­мические.

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

 

Как уже говорилось, внедрение всех операторов SQL кроме SELECT не вызывает особых проблем при разработке программ на базовых языках. Простое же внедрение оператора SELECT в текст программы приводит к тому, что результирующий набор данных будет состоять только из одной строки соответствующей таблицы. Это обусловлено тем, что операторы языков программи­рования высокого уровня работают только с отдельными элемен­тами, представляющими собой отдельные строки данных, в то время как оператор языка SQL может обрабатывать произвольное число строк данных. Для устранения такой несогласованности в языке SQL предусмотрены специальные функции, позволяющие связывать переменные базового языка со строками таблиц баз дан­ных, которые обрабатываются (возвращаются) по одной при каж­дом последовательном обращении. С учетом этого все запросы на языке SQL подразделяют на две группы: однострочные и много­строчные. Очевидно, что результатом выполнения однострочного запроса является только одна строка данных. Результатом же вы­полнения многострочного запроса могут быть структуры, состо­ящие из произвольного числа строк от нуля до п.

Однострочные запросы. Язык SQL для реализации внедренных однострочных запросов предусматривает использование специ­ального оператора единичной выборки с форматом, не отлича­ющимся от формата оператора SELECT, за исключением допол­нительной конструкции INTO, предназначенной для указания имен переменных базового языка, в которые следует поместить результаты запроса. Конструкция INTO должна следовать непос­редственно за списком полей оператора SELECT. Между выра­жениями в списке SELECT и переменными базового языка в конструкции INTO должно существовать взаимно-однозначное соответствие для обеспечения выборки сведений из таблицы базы данных.

Рассмотрим пример. Пусть необходимо выбрать сведения о вла­дельце недвижимости с номером С021 из таблицы с именем Privat-Ower.

Используем следующую конструкцию оператора SELECT:

 

Здесь значение столбца f Name будет помещено в переменную базового языка f irstName, значение столбца IName — в перемен­ную lastName, а значение столбца address — в переменную address (вместе с индикатором значения NULL, для которого использу­ется переменная adresslnd).

Естественно, все применяемые в данном операторе перемен­ные должны быть объявлены заранее согласно правилам базового языка.

Многострочные запросы. Для реализации запросов, в результа­те выполнения которых может быть получено произвольное коли­чество строк, язык SQL предоставляет программисту механизмы выборки данных, основанные на использовании курсоров.

Например, в языке PL/SQL курсор позволяет программе пост­рочно обрабатывать результаты выполнения запроса, т.е. в этом случае он представляет собой указатель на определенную строку в результирующем наборе данных. Курсор можно передвигать с од­ной строки на другую и после обработки одной строки перехо­дить к следующей.

Перед работой курсор должен быть объявлен и открыт, а после завершения работы — закрыт.

Для объявления курсора используется следующая структура:

Рассмотрим пример текста программы, объявляющей курсор:

 

В данном примере объявляется курсор с именем propertyCursor для выбора данных из таблицы PropertyForRent по полям propertyNo, street, city при условии, что значение переменной staff No равно 'SL41'

Для открытия объявленного курсора применяется оператор OPEN, имеющий следующую структуру:

 

После открытия курсора производится выбор информации из таблицы с применением оператора FETCH согласно заданным в курсоре условиям:

 

При обработке оператора FETCH значение столбца propertyNo будет помещено в переменную базового языка propertyNo, а зна­чение столбцов street и city — соответственно в переменные street и city.

Поскольку при выполнении запроса оператор FETCH обраба­тывает только одну строку таблицы, в тексте программы на базо­вом языке он должен быть помещен внутрь соответствующего цикла, обеспечивающего требуемое число просмотров всех запи­сей таблицы. В этом случае СУБД помещает в переменную SQLCODE значение NOT FOUND.

Если таблица не содержит ни одной строки данных, при вы­полнении запроса в первом же шаге цикла будет обнаружено их отсутствие и переменной SQLCODE вернется значение NOT FOUND.

После выполнения запроса курсор должен быть закрыт с по­мощью оператора CLOSE, имеющего следующую структуру: