ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 12.04.2021

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

Скачиваний: 3

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

Практическое

занятие

 9

Знакомство

с

 CALL-

интерфейсом

Практика

 2 

часа

 (

Лекции

 7,8)

На

данном

занятии

мы

освоим

основы

использования

  CALL-

интерфейса

СУБД

ЛИНТЕР

на

примере

открытия

соединения

выполнения

  SELECT-

запросов

обработки

ответов

и

закрытия

соединения

На

этом

примере

мы

получим

общие

навыки

подключения

CALL-

интерфейса

и

использования

функции

 inter. 

9.1. 

Сборка

программы

с

 CALL-

интерфейсом

Для

сборки

программы

с

 CALL-

интерфейсом

необходимо

определить

символ

  

_VER_MAX=<

версия

ЛИНТЕР

где

  <

версия

ЛИНТЕР

>  - 

это

число

полученное

  <

как

первый

номер

версии

>*100  + 

<

второй

номер

версии

>*10; 

например

для

 5.7 

это

будет

 570, 

а

для

 5.9 – 590; 

прописать

пути

для

директивы

  #include 

в

директорию

  intlib 

дистрибутива

ЛИНТЕР

для

 Windows 

надо

определить

еще

символ

препроцессора

 INTER_MSWINDOWS; 

включить

в

сборку

библиотеку

 intlib:  

в

среде

  Windows 

это

может

быть

статическая

библиотека

  inter325.lib, 

расположенная

в

одной

из

поддиректорий

директории

  intlib  (

в

зависимости

от

компилятора

), 

либо

динамически

подключаемая

библиотека

  inter325.dll, 

соответствующая

библиотека

импорта

  inter325.lib 

находится

в

директории

  intlib/

lib; 

в

среде

  Unix 

просто

используется

объектный

файл

  intlib.o, 

расположенный

в

поддиректории

 intlib 

дистрибутива

либо

вместо

подключения

библиотеки

можно

подключить

непосредственно

исходный

текст

 CALL-

интерфейса

 intlib/intlib.c. 

В

среде

  Windows 

в

дистрибутиве

ЛИНТЕР

имеется

файл

  Definition, 

который

конфигурируется

при

установке

системы

Он

включает

все

необходимые

определения

и

может

быть

просто

включен

в

 make-

файл

Примеры

использования

  CALL-

интерфейса

и

соответствующие

  make-

файлы

имеются

в

директориях

 samples/call 

и

 samples/c 

дистрибутива

ЛИНТЕР

.

Задание

:

Собрать

примеры

простейшего

использования

  CALL-

интерфейса

поставляемые

вместе

с

ЛИНТЕР

.

Указания

Перейдите

в

поддиректорию

 samples/c 

дистрибутива

ЛИНТЕР

.  

Изучите

исходный

текст

примера

  step/step.c. 

Он

содержит

вызовы

команд

  CALL-

интерфейса

  “OPEN”,  “SLCT”,  “GETN” 

и

  “CLOSE”, 

печатая

простую

выборку

сделанную

оператором

 SELECT. 

Изучите

содержимое

 make-

файла

 (

он

содержит

команды

для

сборки

всех

примеров

расположенных

в

поддиректории

 samples/c). 

Соберите

примеры

для

 Unix, 

подайте

команду

 make; 

для

  Windows, 

подайте

команду

  nmake  /f  makefile.vc    (

предполагается

использование

 Microsoft Visual C++).


background image

!

52

П

ра
кт

ич

ес

ко

е

за

ня

ти

е

 8

П

ри
ме

р

со

зд

ан

ия

за

щ

и

щ

ен

но

й

ба

зы

да

нн

ы

х

!

!

 
 

E-

mai

l: 

ma

rke

t@

rele

x.r

u

Убедитесь

в

том

что

запущена

СУБД

ЛИНТЕР

на

демонстрационной

БД

содержащей

таблицу

 PERSON. 

Запустите

исполняемый

файл

примера

 step 

и

просмотрите

результаты

9.2. 

Разработка

собственного

примера

Задание

:

Используя

демонстрационный

пример

из

состава

СУБД

ЛИНТЕР

необходимо

разработать

и

отладить

собственную

программу

использующую

  CALL-

интерфейс

для

выборки

данных

Все

задачи

связаны

с

таблицами

  PERSON, AUTO 

или

 FINANCE 

демонстрационной

БД

ЛИНТЕР

.

Задача

  1

Разработать

программу

которая

запрашивает

начальные

буквы

имени

человека

  (

поле

  PERSON.NAME), 

и

выводит

данные

обо

всех

людях

имя

которых

начинается

с

этих

букв

и

о

марке

 (MAKE), 

модели

 (MODEL) 

и

серийном

номере

 (SERIALNO) 

автомобилей

  (

таблица

  AUTO), 

принадлежащих

каждому

человеку

  (

таблицы

  PERSON 

и

AUTO 

связаны

по

полю

  PERSONID). 

При

этом

данные

о

человеке

должны

выводиться

одной

строкой

затем

несколько

строк

о

его

автомобилях

затем

данные

о

следующем

человеке

и

т

.

д

.

Задача

  2

Разработать

программу

которая

запрашивает

начальные

буквы

марки

автомобиля

 (AUTO.MAKE) 

и

выполняет

запрос

на

выборку

данных

соответствующих

этим

маркам

после

чего

печатает

количество

ответов

и

запрашивает

номер

строки

которую

надо

отобразить

После

ввода

номера

строки

программа

должна

отобразить

данные

этой

строки

и

снова

запросить

новый

номер

  (

до

тех

пор

пока

пользователь

не

введет

недопустимое

значение

номера

).

Задача

  3

Разработать

программу

которая

запрашивает

название

кредитной

карты

(

первые

несколько

букв

поля

 CRDITCRD 

таблицы

 FINANCE) 

и

выводит

имена

всех

людей

(PERSON.NAME), 

владеющих

картой

данного

типа

 (

таблицы

 PERSON 

и

 FINANCE 

связаны

по

полю

  PERSONID). 

При

этом

программа

должна

запрашивать

порядок

сортировки

имен

при

печати

по

возрастанию

или

по

убыванию

Напечатав

список

имен

программа

снова

должна

запросить

порядок

вывода

имен

после

чего

выводит

их

  (

возможно

уже

в

другом

порядке

и

так

далее

пока

пользователь

не

введет

команду

выхода

.

Задача

  4

Разработать

программу

которая

запрашивает

уникальный

идентификатор

человека

  (PERSON.PERSONID). 

После

ввода

идентификатора

программа

выводит

имя

человека

  (PERSON.NAME) 

и

выдает

список

всех

автомобилей

которыми

владеет

данный

человек

  (

произвольный

набор

колонок

из

таблицы

  AUTO 

по

желанию

разработчика

таблицы

  AUTO 

и

  PERSON 

связаны

по

полю

  PERSONID). 

Далее

программа

запрашивает

новый

идентификатор

и

т

.

д

., 

пока

пользователь

не

введет

 –1.

Задача

  5

Разработать

программу

которая

запрашивает

величину

жалованья

человека

  (

поле

  SALARY 

таблицы

  PERSON). 

После

этого

программа

должна

выдать

информацию

  (

идентификатор

  (PERSONID), 

имя

  (NAME), 

должность

  (JOB) 

и

жалованье

о

десяти

людях

жалование

которых

наиболее

близко

к

введенному

значению

.


background image

Практическое

занятие

 10

Углубленное

изучение

 CALL-

интерфейса

Практика

 6 

часов

 (

Лекция

 9)

На

занятии

будут

приведены

примеры

иллюстрирующие

работу

с

СУБД

ЛИНТЕР

через

прикладной

интерфейс

низкого

уровня

 Intlib (CALL-

интерфейс

). 

Будут

рассмотрены

следующие

вопросы

обработка

ошибок

с

использованием

 GETE; 

использование

 DML/DDL 

запросов

работа

с

 BLOB-

столбцами

работа

с

подчиненными

курсорами

обработка

транзакций

получение

структуры

ответа

асинхронное

выполнение

запроса

10.1. 

Использование

 DML/DDL 

запросов

обработка

ошибок

Алгоритм

работы

примера

 prac10_e1.c 

таков

:  

1.

Открывается

канал

2.

Удаляется

таблица

  AUTO, 

и

при

ошибке

выводится

текст

с

помощью

команды

GETE. 

3.

Создается

таблица

  AUTO, 

и

при

ошибке

выводится

текст

с

помощью

команды

GETE. 

4.

Закрывается

канал

Следует

обратить

внимание

на

то

что

запросы

  DML/DDL  (

все

кроме

  SELECT), 

подаются

с

четырьмя

пробелами

в

поле

 Command: 

  memcpy(Cbl.Command,"    ",4);   /* Non SELECT command */ 

  inter(&Cbl,NULL,"drop table auto;",NULL,NULL); 

Для

получения

информации

о

произошедшей

ошибке

во

время

компиляции

или

выполнения

запроса

предназначена

команда

  GETE. 

В

примере

рассматривается

применение

данной

команды

для

получения

текстового

сообщения

от

ядра

о

произошедшей

ошибке

 (

функция

 PrintError). 

memcpy(pCBL->Command,"GETE",4);       /* Get error text */ 

pCBL->RowId = pCBL->CodErr; 

pCBL->LnBufRow = MAXSTRLEN; 

inter(pCBL,NULL,NULL,NULL,szErrorText); 

if (pCBL->CodErr != NORMAL) 

  printf("

Ошибка

обработки

 GETE

: %ld\n", pCBL->CodErr); 

else 

{


background image

!

54

П

ра
кт

ич

ес

ко

е

за

ня

ти

е

10. 

Уг
лу
бл

ен

но

е

из

уч

ен
ие

C
A

L

L-

ин

те

рф

ей

са

!

!

 
 

E-

mai

l: 

ma

rke

t@

rele

x.r

u

  realLen = (pCBL->LnBufRow < realLen - 1) ? pCBL->LnBufRow 
: realLen; 
  printf("

Сообщение

: %s\n", szErrorText); 

Для

получения

текстового

сообщения

заполняется

поле

  RowId 

номером

ошибки

ЛИНТЕР

,  LnBufRow 

длиной

буфера

под

сообщение

Адрес

буфера

передается

как

последний

параметр

функции

 inter. 

При

успешном

завершении

функции

в

буфере

находится

текстовое

сообщение

об

ошибке

которое

в

примере

выводится

на

экран

Для

демонстрации

примера

необходимо

чтобы

существовала

таблица

  ERRORS 

с

описаниями

ошибок

Если

данная

таблица

отсутствует

то

сообщение

об

ошибках

будет

выглядеть

так

Linter return code: 2202

10.2. 

Работа

с

 BLOB-

столбцами

Алгоритм

работы

примера

 prac10_e2.c 

таков

:  

1.

Открывается

канал

2.

Делается

попытка

создания

таблицы

 TFILE. 

3.

Предлагается

меню

в

котором

в

таблицу

добавляется

запись

в

  BLOB-

поле

которой

загружается

указанный

пользователем

файл

делается

выборка

из

таблицы

и

выгружаются

данные

  BLOB-

поля

в

файл

из

строки

указанной

пользователем

18.

Закрывается

канал

Следует

обратить

внимание

на

то

что

при

занесении

 BLOB-

данных

можно

указать

тип

 (

целое

число

), 

передаваемое

в

параметре

 RowId. 

  memcpy(pCbl->Command,"AOBJ",4); 
  pCbl->RowId = 0; 
  pCbl->LnBufRow = realLen; 
  inter(pCbl,NULL,NULL,NULL,buf); 

При

получении

 BLOB-

данных

следует

иметь

в

виду

что

передаваемая

в

параметре

RowId 

позиция

начинается

с

единицы

  long beginPos = 1; 
… 
  memcpy(pCbl->Command,"GOBJ",4); 
  pCbl->RowId = beginPos; 
  pCbl->LnBufRow = blobPortion; 
  inter(pCbl,NULL,NULL,NULL,buf); 
… 
  beginPos += realLen; 

Работы

с

данными

из

  BLOB-

столбца

с

минимальным

номером

используются

команды

  AOBJ,  COBJ 

и

  GOBJ. 

Для

работы

с

другими

  BLOB-

столбцами

  (

с

указанием

номера

следует

использовать

команды

 ABLB, CBLB 

и

 GBLB.

Обучаемым

необходимо

самостоятельно

решить

одну

из

следующих

задач

.


background image

!

!

П

ра
кт

ич

ес

ко

е

за

ня

ти

е

10. 

Уг
лу
бл

ен

но

е

из

уч

ен
ие

C
A

L

L-

ин

те

рф

ей

са

!

55

 
 

E-

mai

l: 

ma

rke

t@

rele

x.r

u

Задача

  1.

Модифицировать

данный

пример

добавив

возможность

очистки

всей

таблицы

и

удаления

указанных

записей

.

Задача

  2.

Модифицировать

данный

пример

добавив

возможность

очистки

содержимого

 BLOB-

ячейки

и

добавления

данных

в

конец

существующей

 BLOB-

ячейки

.

Задача

  3.

Модифицировать

данный

пример

добавив

в

таблицу

поле

  FSOURCE, 

в

котором

будет

располагаться

исходный

текст

данного

исполняемого

файла

  (

если

он

существует

в

директории

данного

файла

). 

Например

пользователь

указывает

имя

файла

 /

home/linter/prac10/prac10_e2, 

тогда

добавляется

новая

запись

в

столбец

  FCONTENT 

загружается

этот

файл

а

в

столбец

  FSOURCE 

добавляется

файл

  /home/linter/prac10/

prac10_e2.c. 

Задача

  4.

Модифицировать

данный

пример

следующим

образом

если

для

указанного

имени

файла

существует

файл

  *.c  (

с

расширением

  ‘c’), 

то

он

добавляется

следующей

строкой

и

ему

присваивается

тип

  1. 

Если

существует

файл

  *.h, 

то

он

также

добавляется

новой

строкой

и

ему

присваивается

тип

 2. 

10.3. 

Работа

с

подчиненными

курсорами

обработка

транзакций

Как

уже

известно

клиентское

приложение

для

работы

с

БД

должно

открыть

канал

связи

  (

соединение

). 

При

открытии

канала

приложение

должно

указать

имя

ЛИНТЕР

-

сервера

с

которым

должно

быть

установлено

соединение

а

также

регистрационные

данные

для

проверки

санкционированного

доступа

  (

имя

пользователя

и

пароль

под

которыми

приложение

будет

зарегистрировано

как

пользователь

БД

). 

Через

соединение

могут

быть

открыты

подчиненные

каналы

называемые

курсорами

Для

открытия

курсора

приложению

уже

не

нужно

указывать

регистрационные

данные

  – 

курсоры

наследуют

эту

информацию

от

соединения

которому

они

подчинены

Это

удобно

использовать

когда

приложение

должно

обрабатывать

различные

запросы

направляемые

к

одной

и

той

же

БД

можно

не

открывать

несколько

соединений

а

использовать

несколько

курсоров

Механизм

соединений

и

курсоров

используется

СУБД

ЛИНТЕР

для

управления

транзакциями

Изменения

данных

в

БД

прошедшие

по

некоторому

курсору

могут

фиксироваться

  (

откатываться

независимо

от

работы

по

другим

курсорам

соединения

однако

фиксация

/

откат

по

соединению

вызовет

фиксацию

/

откат

по

всем

подчиненным

курсорам

Пример

  prac10_e3.c 

иллюстрирует

работу

канала

и

двух

подчиненных

курсоров

Алгоритм

его

работы

таков

1.

Открывается

канал

2.

Делается

попытка

создания

таблицы

 PRAC12_T1. 

3.

Открываются

два

курсора

 (

в

оптимистичном

режиме

обработки

транзакций

). 

4.

Предлагается

меню

в

котором

в

таблицу

добавляется

запись

по

любому

из

курсоров

из

таблицы

удаляются

все

записи

по

любому

из

курсоров

делается

выборка

из

таблицы

по

любому

из

курсоров

фиксируются

изменения

по

любому

из

курсоров

откатываются

изменения

по

любому

из

курсоров

19.

Закрывается

канал

Студенты

должны

попробовать

выполнять

разные

действия

по

разным

курсорам

и

посмотреть

как

работает

механизм

подчиненных

курсоров

Следует

обратить

внимание

на

то

что

номер

родительского

канала

устанавливается

в

 CBL 

дочернего

Следующим

образом

  Cursor[i].NumChan = Cbl.NumChan; 

  Cursor[i].PrzExe = M_OPTIMISTIC; 

  memcpy(Cursor[i].Command,"OCUR",4);    /* Open cursor */