Лекции №25,26 (2 и 7.12.2004)

advertisement
Внедренный (встроенный) SQL.
Добавляет к обычному языку программирования (C в наших
примерах) определенные операторы представляющие SQL
команды.
 Каждый внедренный SQL оператор отмечается ключевыми
словами EXEC SQL, идущими перед оператором.
 Препроцессор преобразует C + SQL в чистый C.
 SQL операторы заменяются вызовами соответствующих
процедур.
Разделяемые (хост-) переменные.
Специальное место для объявления переменных, которые
доступны в SQL и C.
 Описание переменных помещается в специальную
секцию между EXEC SQL BEGIN DECLARE SECTION;
и EXEC SQL END DECLARE SECTION;
 В Oracle Pro/C выделение такой секции не обязательно (в
С++ - обязательно).
 C переменные используются как обычно, в SQL
командах перед именем переменной должно ставиться
двоеточие (:).
Пример.
Найти цену данного пива в данном баре Sells(bar, beer, price).
EXEC SQL BEGIN DECLARE SECTION;
char theBar[21], theBeer[21];
float thePrice;
int priceInd;
EXEC SQL END DECLARE SECTION;
...
/* присвоить значения theBar и theBeer */
...
EXEC SQL SELECT price
INTO :thePrice
FROM Sells
WHERE beer = :theBeer
AND bar = :theBar;
...
Что произойдет, если цена NULL? Используется так
называемая индикативная переменная
EXEC SQL SELECT price
INTO :thePrice :priceInd
FROM Sells
WHERE beer = :theBeer
AND bar = :theBar;
if (priceInd = = -1)
{
… /* обработка ситуации когда price=NULL */
};
...
Курсоры.
Подобны PL/SQL курсорам с некоторыми синтаксическими
отличиями.
Пример. Печать меню бара Joe’s.
Sells(bar, beer, price)
EXEC SQL BEGIN DECLARE SECTION;
char theBeer[21];
float thePrice;
EXEC SQL END DECLARE SECTION;
EXEC SQL DECLARE c CURSOR FOR
SELECT beer, price
FROM Sells
WHERE bar = 'Joe''s Bar';
EXEC SQL OPEN CURSOR c;
while(1)
{
EXEC SQL FETCH c
INTO :theBeer, :thePrice;
if(NOT FOUND) break;
/* format and print beer and price */
}
EXEC SQL CLOSE CURSOR c;
Oracle в сравнении с SQL.
 SQL имеет FROM в fetch-утверждении перед именем
курсора.
 SQL определяет массив символов SQLSTATE, получающий
определенные значения каждый раз при вызове системы.
 Здесь присутствуют сигналы об ошибках.
 Сигнал о том, что курсор не находит более кортежей.
 Oracle предоставляет заголовочный файл sqlca.h,
который определяет коммуникационную область
(communication area) и набор макроопределений для
доступа к этой области.
 В частности, NOT FOUND – это макроопределение,
сигнализирующее о том, что был получен сигнал
«больше-нет-кортежей»
Динамический SQL.
Мотивировка:
 Внедренный SQL удобен для устойчивых приложений,
например, когда используется клерком для резервирования
авиабилета.
 Однако он не может быть использован для написания
программ типа sqlplus, поскольку требуется компилировать
код для sqlplus перед тем, как станут известны SQL
операторы, набранные в ответ на подсказку SQL>
 Два специальных оператора внедренного SQL:
 PREPARE преобразует (компилирует) символьную
строку в SQL запрос.
 EXECUTE выполняет этот запрос.
Пример: Набросок программы для Sqlplus
EXEC SQL BEGIN DECLARE SECTION;
char query[MAX_QUERY_LENGTH];
EXEC SQL END DECLARE SECTION;
/* issue SQL> prompt */
/* read user's text into array query */
EXEC SQL PREPARE q FROM :query;
EXEC SQL EXECUTE q;
/* go back to reissue prompt */
 Однажды скомпилированный (приготовленный) запрос
может выполняться много раз.
 Во время компиляции запроса с помощью PREPARE
происходит оптимизация запроса – поиск такого способа
(плана) исполнения запроса, который бы использовал
меньше процессорного времени и дисковых операций
ввода/вывода.
 С другой стороны PREPARE и EXECUTE могут быть
объединены в:
EXEC SQL EXECUTE IMMEDIATE :query;
Интерфейс CLI (Call-Level Interface).
Более современным подходом к объединению процедурного
языка программирования с SQL является интерфейс CLI, в
котором C-программа (или программа на каком-либо другом
языке) создает SQL операторы как символьные строки и
передает их функциям, являющимся частью стандартной
библиотеки.
 Это похоже на то, что в действительности происходит в
приложениях, использующих внедренный SQL.
 Два основных подхода: SQL/CLI ( ODBC - open database
connectivity- стандарт) и JDBC (Java database connectivity).
CLI
 В C вызов библиотечной функции создает дескриптор
оператора = структура, в которую можно поместить SQL
оператор. Подробнее описано в книге.
 Вызов SQLPrepare(myHandle, <statement>,...) используется
для передачи SQL оператора вторым аргументом и его
компиляции.
 Вызов SQLExecute(myHandle) используется для
выполнения скомпилированного оператора.
Пример.
SQLPrepare(handle1, "SELECT beer, price
FROM Sells
WHERE bar = 'Joe''s Bar'");
SQLExecute(handle1);
Извлечение данных.
Для получения доступа к данным, возвращенным
исполняемым оператором, необходимо:
1. Связать переменные с номерами компонент возвращаемого
кортежа.
 SQLBindCol использует дескриптор оператора, номер
столбца, тип и имя переменной плюс некоторые
другие аргументы.
2. Извлечь данные, используя оператор FETCH, в котором
используется дескриптор SQL оператора.
Пример.
SQLBindCol(handle1, 1, SQL_CHAR, &theBar,...)
SQLBindCol(handle1, 2, SQL_REAL, &thePrice,...)
SQLExecute(handle1);
...
while(SQLFetch(handle1) !=SQL_NO_DATA)
{
... /* обработка извлеченных данных */
}
Авторизация в SQL.
 Файловые системы задают некоторые привилегии для
работы с файлами: r, w, x.
При частичной аналогии SQL определяет 9 привилегий
доступа для отношений, из которых наиболее важными
являются:
1. SELECT = право на выполнение запроса для отношения.
2. INSERT = право вставлять кортежи в отношение - может
относиться к отдельному атрибуту, в этом случае
привилегия задает только одного столбца вставляемого
кортежа
3. DELETE = право удалять кортежи из отношения
4. UPDATE = право обновлять кортежи отношения - может
относиться к отдельному атрибуту.
Выдача(делегирование) привилегий.
Вы имеете все возможные привилегии для отношений,
которые вы сами создаете.
Вы можете делегировать привилегии любому другому
пользователю, если вы имеете саму привилегию и право ее
делегирования (привилегию с режимом grant).
 Вы имеете этот режим для ваших собственных отношений.
Пример.
1. Sally может выполнять запросы для Sells и может изменять
цены, но не может передать эту привилегию.
GRANT SELECT ON Sells, UPDATE(price) ON Sells TO
sally;
2. Sally может выборочно делегировать эти привилегии
другому:
GRANT SELECT ON Sells, UPDATE(price) ON Sells TO sally
WITH GRANT OPTION;
Лишение привилегий.
 Привилегия, делегированная вам кем-то другим, может
быть отобрана.
 Синтаксис похож на оператор делегирования, но
использует REVOKE ... FROM вместо GRANT ... TO.
 Определение, имеете ли вы конкретную привилегию, может
быть нетривиальной задачей, использующей граф
делегирования (подробнее см. книгу). Основными
принципами здесь являются:
a) если привилегия была делегирована вам несколькими
пользователями, то для лишения этой привилегии все эти
пользователи должны ее отобрать.
b) Отбор привилегии является транзитивным. Если A
делегировал P to B , который делегирована P to C , затем А
отбирает P у B , то автоматически P будет отобрана у C .
Download