Интернет магазин китайских планшетных компьютеров



Компьютеры - SQLJ - Синтаксис

05 июня 2011


Оглавление:
1. SQLJ
2. Пример кода
3. SQLJ и JDBC
4. Синтаксис
5. Взаимодействие с JDBC
6. Особенности SQLJ
7. Недостатки SQLJ



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

Любые SQLJ-конструкции начинаются с директивы #sql, в частности, блоки, содержащие внутри себя собственно SQL-запросы, задаются как #sql {…}.

Внешние переменные

В терминологии SQLJ внешней переменной называется переменная SQLJ-конструкции, используемая для получения значений или передачи их во внешнюю относительно конструкции программную среду. К примеру:

int i, j;
i = 1;
#sql {    SELECT field INTO :OUT j
            FROM table
            WHERE id = :IN i };
System.out.println;

Внешние переменные для избежания неоднозначностей должны задаваться в определённом виде, а именно:

: <имя переменной>.

Модификаторы IN, OUT, INOUT опциональны и используются для указания переменных, соответственно, передающих значение извне в SQLJ-конструкцию; возвращающих значение вовне и выполняющих обе функции. Данные ключевые слова используются не только для этого — также они задают метод доступа к внешним переменным внутри SQLJ-конструкции: при наличии модификатора IN возможно только чтение значения переменной, при наличии OUT — только запись, при наличии INOUT — полный доступ. По умолчанию переменные объявляются с неявным модификатором INOUT.

Внешние выражения

Вместо просто переменных в SQLJ-конструкциях можно использовать выражения, содержащие внешние переменные, чаще называемые просто внешними выражениями. Они имеют определённый синтаксис:

:

Основной нюанс при использовании внешних выражений заключается в том, что их использование может повлечь за собой определённые последствия, связанные с тем, что разбор SQLJ-конструкции препроцессором при наличии нескольких внешних выражений идёт в определённом порядке, а при использовании в выражениях присваиваний результат присваивания может быть передан в программную среду.

Для иллюстрации данных двух моментов разберем простой пример использования внешних выражений:

int i = 1;
#sql {    SELECT result
            FROM  table1
            WHERE field1 = : AND field2 = : AND field3 = : };
System.out.println;

Исходя из опыта программирования, можно попытаться предположить, что

  1. Значение переменной i в процессе разбора SQL-выражения не будет изменяться;
  2. Сформированный запрос будет иметь вид
SELECT RESULT
    FROM    table1
    WHERE   field1 = : AND field2 = : AND field3 = :

Однако и первое, и второе утверждения — неверны. Для проверки этого составим простую схему, проясняющую порядок разбора данной конструкции SQLJ-препроцессором:

i = 1
x → x, i = 2
y → y, i = 3
z → z, i = 4

Следовательно:

  1. После выполнения SQLJ-директивы будет иметь место i = 4;
  2. Выполняться будет запрос
SELECT RESULT
    FROM    table1
    WHERE   field1 = : AND field2 = : AND field3 = :

Контексты

В терминологии SQLJ и JDBC контекстом подключения называется совокупность из трёх параметров, однозначно ими определяемая:

  1. название базы данных;
  2. идентификатор сессии;
  3. идентификатор активной транзакции.

Для любой SQLJ-конструкции контекст, в котором она будет исполняться, можно определить явно: #sql {…}.

В рамках директивы #sql можно также создавать новые контексты для последующего использования: #sql context <контекст>. Если контекст явно не задан, то конструкция считается выполняемом в контексте по умолчанию. При необходимости контекст по умолчанию может быть изменён.

Итераторы

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

Стандартом предусмотрены два типа итераторов — разница между ними достаточно интересна: итераторы с привязкой по позиции в использовании требуют более SQL-подобного синтаксиса, в отличие от итераторов с привязкой по столбцам, которые очень близки по использованию к объектам.

Итераторы с привязкой по позиции

Первым типом итератора является итератор с привязкой по позициям. Он объявляется следующим образом: #sql public iterator ByPos. Ясно видно, что в данном случае привязка результатов запроса к итератору осуществляется просто по совпадению типов данных между итератором и результатом запроса. Однако для этого требуется, чтобы типы данных у итератора и результата запроса могли быть отображены друг на друга согласно стандарту SQL/JRT.

Создадим простую таблицу:

CREATE TABLE people (
        fullname VARCHAR,
        birthyear NUMERIC)

Теперь с помощью итератора первого типа и конструкции FETCH … INTO … произведем выборку данных из результата запроса:

ByPos positer;
String name = null;
int year = 0;
#sql positer = {SELECT fullname, birthyear FROM people};
for
{
        #sql {FETCH :positer INTO :name, :year};
        if )
                break;
        System.out.println;
 
}

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

Итераторы с именованием столбцов

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

#sql public iterator ByName (
        String fullNAME,
        int birthYEAR);

Используется он как обычный объект, а именно, доступ к полям осуществляется через соответствующие акцессорные методы:

ByName namiter;
#sql namiter = {SELECT fullname, birthyear FROM people};
String s;
int i;
while )
{
        i = namiter.birthYEAR;
        s = namiter.fullNAME;
        System.out.println;
}

Однако существует правило, которое должно быть соблюдено — имена полей итератора должны совпадать с именами полей в запросе. Это связано с процессом разбора SQLJ-конструкции препроцессором. В случае, если имя столбца в БД имеет название, несовместимое с правилами именования переменных в Java, необходимо использовать в запросе, формирующем итератор, псевдонимы.

Вызовы процедур и функций

Вызовы процедур очень просто записываются с использованием внешних переменных

#sql {CALL proc };

Функции, в свою очередь, вызываются с использованием конструкции VALUE

int i;
#sql i = {VALUES)};


Просмотров: 5744


<<< Swing