Линтер методичка
.pdf
|
processing_error(lRet, 0, nCurs, 0,"Error |
|
П |
ExecuteDirect"); |
|
|
||
ра |
|
|
кт |
printf("Inserting ["); |
|
ич |
||
ес |
if (lRet = LINTER_ExecuteDirect(nCurs, "insert into |
|
ко |
PRAC12_STUDENT values (1, 'Petrov A.I.', 5, 6);", 0, |
|
е |
||
NULL,NULL)) |
||
за |
||
ня |
processing_error(lRet, 0, nCurs, 0,"Error |
|
ти |
ExecuteDirect"); |
|
е |
||
printf("."); |
||
11. |
||
Ос |
if (lRet = LINTER_ExecuteDirect(nCurs, "insert into |
|
но |
||
вн |
PRAC12_STUDENT values (2, 'Voronin M.V.', 2, 1);", 0, |
|
ые |
NULL,NULL)) |
|
пр |
processing_error(lRet, 0, nCurs, 0,"Error |
|
ие |
||
м |
ExecuteDirect"); |
ыprintf(".");
ис |
if (lRet = LINTER_ExecuteDirect(nCurs, "insert into |
по |
|
ль |
PRAC12_STUDENT values (3, 'Dzuba R.A.', 3, 4);", 0, |
зо |
NULL,NULL)) |
ва |
processing_error(lRet, 0, nCurs, 0,"Error |
ни |
яExecuteDirect");
Li |
printf("."); |
|
n |
||
A |
printf("]\n"); |
|
PI |
||
|
||
!61 |
printf("Cursor closing\n"); |
|
|
||
|
if (lRet = LINTER_CloseCursor(nCurs)) |
|
|
processing_error(lRet, 0, nCurs, 0,"Error CloseCursor"); |
|
|
printf("Connection closing\n"); |
|
|
if (lRet = LINTER_CloseConnect(nConn)) |
|
|
processing_error(lRet, nConn, 0, 0, "ERROR |
|
|
CloseConnect"); |
|
E- |
printf("LINTER_CloseAPI\n"); |
|
mai |
||
l: |
||
ma |
|
|
rke |
|
|
t@ |
|
|
rele |
|
|
x.r |
|
|
u |
|
62!
П |
LINTER_CloseAPI(); |
/* Free library resource */ |
ра |
|
|
кт |
printf("Done.\n"); |
|
ич |
|
|
ес |
return 0; |
|
ко |
|
|
/* End */ |
|
|
е |
|
|
за |
} |
|
ня |
|
|
ти |
|
|
еСкомпилируем этот файл:
11.gcc prac12_e1.c -I /export/home/lindesk/linter5923/linter/
Ос |
intlib/ -llinapi -lsocket -lm -L /export/home/lindesk/ |
но |
|
вн |
linter5923/linter/intlib/ -o prac12_e1 |
ые |
Задача 1. (Студенты выполняют самостоятельно) Модифицировать данный |
пример таким образом, чтобы входные данные задавались пользователем, а первичный
ключ определялся приложением, как минимальный из положительных чисел.
ие
м11.3. Использование параметризованных запросов
ы |
Ниже представлен пример (prac12_e2.c ), в котором консольное приложение |
|
позволяетис |
пользователю ввести маску для поиска данных в таблице, и, используя оператор, |
|
выполняет параметризированный запрос. |
||
по |
|
|
ль |
#include <stdio.h> |
|
зо |
#include <stdlib.h> |
|
ва |
|
|
ни |
|
|
я |
#include "linapi.h" |
|
Li |
|
|
n |
|
|
A |
#if defined(VXWORKS) |
/* 05.03.02 */ |
PI |
||
|
#include "vxstart.h" |
|
|
#endif |
|
|
|
#ifdef _BCPP_
extern unsigned _stklen = 16383; #endif
/* function for error processing for LinAPI */
void processing_error(LONG ret_cod,
E-
mai WORD con_id,
l: ma rke t@ rele x.r
u
|
WORD cur_id, |
|
П |
WORD stmt_id, |
|
ра |
char * message) |
|
кт |
||
{ |
||
ич |
||
ес |
LONG lRet; |
|
ко |
еLONG apierr = 0, error = 0, syserr = 0;
за |
|
|
ня |
|
|
ти |
if ( ret_cod == LINAPI_ERROR ) |
|
е |
||
{ |
||
11. |
||
Ос |
/* getting error codes for required object */ |
|
но |
||
вн |
if (lRet = LINTER_Error(con_id, cur_id, stmt_id, |
|
ые |
&apierr, &error, &syserr, NULL, NULL)) |
|
пр |
||
ие |
printf("diagnostic error %ld\n",lRet); |
|
м |
||
else |
||
ы |
||
ис |
{ |
|
по |
||
ль |
printf("ApiErr = %ld, LinErr = %ld, SysErr = %ld\n%s |
|
зо |
\n", |
|
ва |
apierr, error, syserr, message); |
|
ни |
||
я |
if ( (apierr == eLinterError) && error > 2000 && error |
|
Li |
||
n |
< 3000) |
|
A |
{ |
|
PI |
||
/* getting string and position if syntax error is */ |
||
!63 |
||
printf("Syntax error : line %d, position %d\n", |
||
|
||
|
(short)syserr, *(short*)((char*)&syserr +2)); |
|
|
} |
|
|
} |
|
|
LINTER_CloseAPI(); /* Free library resource */ |
|
|
exit(1); |
|
|
} |
|
E- |
else |
|
mai |
printf("Return code = %ld\n",ret_cod); |
|
l: |
||
ma |
|
|
rke |
|
|
t@ |
|
|
rele |
|
|
x.r |
|
|
u |
|
64! |
|
|
П |
} |
|
ра |
|
|
кт |
#define MAXSTRLEN 100 |
|
ич |
|
|
ес |
|
|
ко |
#if defined(VXWORKS) |
/* 05.03.02 */ |
е |
||
за |
MainStart(apidata, 32*1024, UninitLinterClient) |
|
ня |
#else |
|
ти |
|
еint main(void)
11. |
#endif |
|
|
|
|
|
Ос |
|
|
|
|
|
но |
{ |
|
|
|
|
вн |
WORD |
nConn; |
/* connection identifier */ |
|
|
ые |
||||
|
пр |
WORD |
nCurs; |
/* cursor identifier |
*/ |
|
ие |
||||
|
WORD |
nStmt; |
/* statement identifier |
*/ |
|
|
м |
||||
|
ы |
LONG |
lRet; |
/* return code */ |
|
|
ис |
|
|||
|
|
|
|
|
|
|
по |
|
|
|
|
|
ль |
char szMask[MAXSTRLEN] = "Y"; |
|
||
|
зо |
|
|||
|
ва |
char nullInd[4]; |
|
|
|
|
ни |
nullInd[0] = 0; |
|
|
|
|
я |
|
|
||
|
Li |
LONG parLen = MAXSTRLEN; |
|
||
|
n |
LONG recCount; |
|
|
|
|
A |
|
|
||
|
PI |
LONG realLen = 0; |
|
|
|
|
|
int i = 0; |
|
|
|
|
|
/* Establish connection */ |
|
||
|
|
|
|||
|
|
|
|||
|
|
printf("\nConnect\n"); |
|
|
|
|
|
|
|||
|
|
if (lRet = LINTER_Connect("SYSTEM", 0, "MANAGER", 0, |
|||
|
|
NULL, mAutocommit, &nConn)) |
|
||
|
|
processing_error(lRet, nConn, 0, 0, "ERROR |
|
||
|
|
Linter_Connect"); |
|
|
|
|
E- |
/* cursor opening for query processing */ |
|
||
mai |
printf("Open cursor\n"); |
|
|||
|
l: |
|
ma rke t@ rele x.r
u
П
ра
кт
ич
ес
ко
е
за
ня
ти
е
11.
Ос
но
вн
ые
пр
ие
м
ы
ис
по
ль
зо
ва
ни
if (lRet = LINTER_OpenCursor(nConn, &nCurs, NULL, 0, mAutocommit))
processing_error(lRet, nConn, 0, 0, "Error open cursor");
printf("Create statement\n");
if (lRet = LINTER_CreateStatement(nCurs, "select * from PRAC12_STUDENT where FIO like :S;", 0, &nStmt))
processing_error(lRet, 0, nCurs, 0,"Error CreateStatement");
printf("Bind parameter\n");
if (lRet = LINTER_BindParameter(nCurs, nStmt, 1, 0, 0, szMask, 1, 1, tString, 0, &parLen))
processing_error(lRet, 0, nCurs, 0,"Error BindParameter");
while (!strcmp(szMask, "Y") || !strcmp(szMask, "y"))
{
яprintf("Input mask for student name \n");
Li
n gets(szMask);
A
PI
parLen = strlen(szMask) + 1;
!65 |
printf("Mask is %s, It's lenght is %d\n", szMask, |
|
|
|
parLen); |
E- mai l: ma rke t@ rele x.r u
printf("Execute statement \n", nStmt);
if (lRet = LINTER_ExecuteStatement(nCurs, nStmt, 0, 0,
0))
processing_error(lRet, 0, nCurs, 0,"Error ExecuteStatement");
realLen = sizeof(recCount);
66!
|
П |
if (lRet = LINTER_GetCursorOption(nCurs, |
|
ра |
cSelectRowCount, 0, &recCount, &realLen)) |
|
кт |
processing_error(lRet, 0, nCurs, 0,"Error |
|
ич |
|
|
GetCursorOption"); |
|
|
ес |
|
|
ко |
|
|
е |
if (recCount) |
|
за |
|
|
ня |
{ |
|
ти |
|
|
printf("Was found %d students.\n", recCount); |
|
|
е |
|
11. |
for (i = 0; i < recCount; i++) |
|
|
Ос |
|
|
но |
{ |
|
вн |
if (lRet = LINTER_Fetch(nCurs, toAbsNumber, i + 1, |
|
ые |
|
|
пр |
1, 0, 0, 0)) |
|
ие |
processing_error(lRet, 0, nCurs, 0,"Error |
|
м |
|
|
ы |
Fetch"); |
|
ис |
if (lRet = LINTER_GetData(nCurs, 2, szMask, |
|
по |
|
|
MAXSTRLEN, tString, 0, 0, &realLen)) |
|
|
ль |
|
|
зо |
processing_error(lRet, 0, nCurs, 0,"Error |
|
ва |
GetData"); |
|
ни |
|
|
printf("%d. %s\n", i + 1, szMask); |
|
|
я |
|
|
Li |
} |
|
n |
|
|
A |
} else |
|
PI |
{ |
|
|
|
|
|
printf("No students found.\n"); |
|
|
} |
|
|
|
|
|
printf("Next search? (Y/N)\n"); |
|
|
gets(szMask); |
|
|
} |
|
|
printf("Cursor closing\n"); |
|
E- |
if (lRet = LINTER_CloseCursor(nCurs)) |
mai |
processing_error(lRet, 0, nCurs, 0,"Error CloseCursor"); |
l: |
|
ma |
|
rke |
|
t@ |
|
rele |
|
x.r |
|
u |
|
printf("Connection closing\n");
Пif (lRet = LINTER_CloseConnect(nConn))
ра |
processing_error(lRet, nConn, 0, 0, "ERROR |
|||
кт |
||||
CloseConnect"); |
|
|
||
ич |
|
|
||
ес |
|
|
|
|
ко |
printf("LINTER_CloseAPI\n"); |
|
||
е |
|
|||
за |
LINTER_CloseAPI(); |
/* Free library resource */ |
||
ня |
||||
|
|
|
||
ти |
|
|
|
|
е |
printf("Done.\n"); |
|
|
|
11. |
|
|
||
Ос |
return 0; |
|
|
|
но |
/* End */ |
|
|
|
вн |
|
|
||
ые |
} |
|
|
|
пр |
|
|
||
|
|
|
||
ие |
Скомпилируем этот файл: |
|
|
|
м |
|
|
||
gcc prac12_e2.c -I /export/home/lindesk/linter5923/linter/ |
||||
ы |
||||
ис |
intlib/ -llinapi -lsocket -lm -L /export/home/lindesk/ |
|||
по |
||||
linter5923/linter/intlib/ -o prac12_e2 |
|
|||
ль |
|
|||
зо |
Задача 2. (Студенты выполняют самостоятельно) |
Модифицировать второй |
||
пример таким образом, чтобы пользователь мог задавать диапазон курсов, групп и |
||||
ва |
|
|
|
|
фамилий студентов. |
|
|
||
ни |
Задача 3. (Студенты выполняют самостоятельно) |
Модифицировать второй |
||
я |
||||
пример таким образом, чтобы выводились только 5 записей, и пользователь осуществлял |
||||
Li |
|
|
|
|
навигацию по выборке (следующие 5, предыдущие 5). |
|
|||
n |
Задача 4. (Студенты выполняют самостоятельно) |
Модифицировать второй |
||
A |
пример таким образом, чтобы выводились только 5 записей, и пользователь осуществлял навигациюPI по выборке (на одну запись ниже, на одну запись выше).
11.4. Получение данных при помощи Fetch
67!
Рассмотрим задачу: пусть требуется из таблицы со студентами создать таблицу со статистикой: сколько человек обучается на каждом курсе. Данную задачу можно решить средствами SQL, но для иллюстрации работы функции LINTER_Fetch будем использовать следующий алгоритм:
•соединяемся с базой данных;
•создаем курсор;
•создаем требуемую таблицу, если она существует, то удаляем ее;
•из данных таблицы накапливаем количество человек на каждом курсе;
•вставляем новые данные в новую таблицу.
Следует обратить внимание, что получение данных осуществляется не подачей команды GetData, а автоматически при каждом смещении по выборке командой Fetch.
E- |
|
Вставка данных осуществляется при помощи динамически формируемых запросов. |
Ониmai |
работают медленней на 10-15%, чем запросы с параметрами, но легче в отладке – |
|
всегдаl: |
можно просмотреть лог-файл ядра и понять, в чем ошибка. |
ma rke t@ rele x.r
u
68!
П |
Ниже представлен листинг программы из файла prac12_e3.c. |
|
#include <stdio.h> |
|
|
ра |
|
|
кт |
#include <stdlib.h> |
|
ич |
|
|
|
|
|
ес |
|
|
ко |
#include "linapi.h" |
|
е |
|
|
за |
|
|
ня |
#if defined(VXWORKS) |
/* 05.03.02 */ |
ти |
||
е |
#include "vxstart.h" |
|
11. |
|
|
#endif |
|
|
Ос |
|
|
но |
|
|
вн |
#ifdef _BCPP_ |
|
ые |
|
|
пр |
extern unsigned _stklen = 16383; |
|
ие |
|
м#endif
|
ы |
|
|
ис |
|
|
по |
/* function for error processing for LinAPI */ |
|
ль |
|
|
зо |
void processing_error(LONG ret_cod, |
|
ва |
WORD con_id, |
|
ни |
|
|
я |
WORD cur_id, |
|
Li |
|
|
WORD stmt_id, |
|
|
n |
|
|
A |
char * message) |
|
PI |
|
|
|
{ |
|
|
LONG lRet; |
|
|
LONG apierr = 0, error = 0, syserr = 0; |
|
|
|
|
|
if ( ret_cod == LINAPI_ERROR ) |
|
|
{ |
|
|
/* getting error codes for required object */ |
|
|
if (lRet = LINTER_Error(con_id, cur_id, stmt_id, |
|
|
&apierr, &error, &syserr, NULL, NULL)) |
mai |
printf("diagnostic error %ld\n",lRet); |
|
|
E- |
|
|
l: |
else |
|
ma |
|
|
rke |
|
|
t@ |
|
rele |
|
|
|
x.r |
|
|
u |
|
|
{ |
|
П |
printf("ApiErr = %ld, LinErr = %ld, SysErr = %ld\n%s |
|
ра |
\n", |
|
кт |
apierr, error, syserr, message); |
|
ич |
||
ес |
if ( (apierr == eLinterError) && error > 2000 && error |
|
ко |
< 3000) |
|
е |
||
{ |
||
за |
||
ня |
/* getting string and position if syntax error is */ |
|
ти |
||
е |
printf("Syntax error : line %d, position %d\n", |
|
11. |
(short)syserr, *(short*)((char*)&syserr +2)); |
|
Ос |
||
но |
} |
|
вн |
||
} |
||
ые |
||
пр |
LINTER_CloseAPI(); /* Free library resource */ |
|
ие |
мexit(1);
ы |
} |
|
|
ис |
|
||
по |
else |
|
|
ль |
|
||
printf("Return code = %ld\n",ret_cod); |
|||
зо |
|||
ва |
} |
|
|
ни |
|
||
я |
|
|
|
Li |
#define MAXSTRLEN 100 |
|
|
n |
|
||
A |
#define MAXKURSNUM 6 |
|
|
PI |
|
||
|
|
||
69! |
#if defined(VXWORKS) |
/* 05.03.02 */ |
|
|
MainStart(apidata, 32*1024, UninitLinterClient) #else
int main(void) #endif
{
E- mai l: ma rke t@ rele x.r u
WORD |
nConn; |
/* connection identifier */ |
|
WORD |
nCurs; |
/* cursor identifier |
*/ |
LONG |
lRet; |
/* return code */ |
|
70! |
|
|
|
П |
LONG i = 0; |
|
ра |
|
|
кт |
LONG realLen = 0; |
|
ич |
|
|
ес |
LONG nKurs = 0; |
|
ко |
|
|
LONG recCount = 0; |
|
|
е |
|
|
за |
LONG statistic[MAXKURSNUM] = {0}; |
|
ня |
|
|
ти |
char szSQL[MAXSTRLEN * 10] = {0}; |
|
е |
|
11. |
|
|
|
Ос |
printf("\nConnect\n"); |
|
но |
|
|
if (lRet = LINTER_Connect("SYSTEM", 0, "MANAGER", 0, |
|
|
вн |
|
|
ые |
NULL, mAutocommit, &nConn)) |
|
пр |
processing_error(lRet, nConn, 0, 0, "ERROR |
|
ие |
|
|
м |
Linter_Connect"); |
|
ы |
|
|
ис |
printf("Open cursor\n"); |
|
по |
|
|
ль |
if (lRet = LINTER_OpenCursor(nConn, &nCurs, NULL, 0, |
|
зо |
|
|
ва |
mAutocommit)) |
|
ни |
processing_error(lRet, nConn, 0, 0, "Error open |
|
я |
|
|
Li |
cursor"); |
|
n |
|
|
A |
if (lRet = LINTER_ExecuteDirect(nCurs, "select * from |
|
PI |
|
|
|
PRAC12_STUDENT;", 0, NULL,NULL)) |
|
|
processing_error(lRet, 0, nCurs, 0,"Error |
|
|
ExecuteDirect"); |
|
|
|
|
|
realLen = sizeof(recCount); |
|
|
if (lRet = LINTER_GetCursorOption(nCurs, cSelectRowCount, |
|
|
0, &recCount, &realLen)) |
|
|
processing_error(lRet, 0, nCurs, 0,"Error |
|
|
GetCursorOption"); |
|
E- |
if (recCount) |
mai |
||
|
l: |
{ |
|
ma |
|
|
rke |
|
|
t@ |
|
rele |
|
|
|
x.r |
|
|
u |
|