LINTER от 04.02.15
.pdfПрактическое занятие 11. Основные приемы использования LinAPI 71
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)) 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 < 3000)
{
/* getting string and position if syntax error is */ printf("Syntax error : line %d, position %d\n",
(short)syserr, *(short*)((char*)&syserr +2));
}
}
LINTER_CloseAPI(); /* Free library resource */ exit(1);
}
else
printf("Return code = %ld\n",ret_cod);
}
#define MAXSTRLEN 100
|
#if defined(VXWORKS) |
/* 05.03.02 */ |
|
|
|
|
|
|
|
|
E-mail: market@relex.ru |
ЗАО НПП «РЕЛЭКС» |
http://www.relex.ru |
|
|
|
|
|
|
E-mail: market@relex.ru |
ЗАО НПП «РЕЛЭКС» |
http://www.relex.ru |
72 Практическое занятие 11. Основные приемы использования LinAPI
MainStart(apidata, 32*1024, UninitLinterClient) #else
int main(void) #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;
LONG parLen = MAXSTRLEN; LONG recCount;
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");
/* cursor opening for query processing */ printf("Open cursor\n");
E-mail: market@relex.ru |
ЗАО НПП «РЕЛЭКС» |
http://www.relex.ru |
|
|
|
Практическое занятие 11. Основные приемы использования LinAPI 73
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");
gets(szMask);
parLen = strlen(szMask) + 1;
printf("Mask is %s, It's lenght is %d\n", szMask, parLen);
printf("Execute statement \n", nStmt);
if (lRet = LINTER_ExecuteStatement(nCurs, nStmt, 0, 0,
0))
E-mail: market@relex.ru |
ЗАО НПП «РЕЛЭКС» |
http://www.relex.ru |
|
|
|
E-mail: market@relex.ru |
ЗАО НПП «РЕЛЭКС» |
http://www.relex.ru |
74 Практическое занятие 11. Основные приемы использования LinAPI
processing_error(lRet, 0, nCurs, 0,"Error ExecuteStatement");
realLen = sizeof(recCount);
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);
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);
}
} else
{
printf("No students found.\n");
E-mail: market@relex.ru |
ЗАО НПП «РЕЛЭКС» |
http://www.relex.ru |
|
|
|
Практическое занятие 11. Основные приемы использования LinAPI 75
}
printf("Next search? (Y/N)\n"); gets(szMask);
}
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");
printf("LINTER_CloseAPI\n");
LINTER_CloseAPI(); /* Free library resource */
printf("Done.\n"); 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. (Студенты выполняют самостоятельно) Модифицировать второй пример таким образом, чтобы пользователь мог задавать диапазон курсов, групп и фамилий студентов.
E-mail: market@relex.ru |
ЗАО НПП «РЕЛЭКС» |
http://www.relex.ru |
|
|
|
E-mail: market@relex.ru |
ЗАО НПП «РЕЛЭКС» |
http://www.relex.ru |
76 Практическое занятие 11. Основные приемы использования LinAPI
Задача 3. (Студенты выполняют самостоятельно) Модифицировать второй пример таким образом, чтобы выводились только 5 записей, и пользователь осуществлял навигацию по выборке (следующие 5, предыдущие 5).
Задача 4. (Студенты выполняют самостоятельно) Модифицировать второй пример таким образом, чтобы выводились только 5 записей, и пользователь осуществлял навигацию по выборке (на одну запись ниже, на одну запись выше).
11.4. Получение данных при помощи Fetch
Рассмотрим задачу: пусть требуется из таблицы со студентами создать таблицу со статистикой: сколько человек обучается на каждом курсе. Данную задачу можно решить средствами SQL, но для иллюстрации работы функции LINTER_Fetch будем использовать следующий алгоритм:
|
соединяемся с базой данных; |
|
создаем курсор; |
|
создаем требуемую таблицу, если она существует, то удаляем ее; |
|
из данных таблицы накапливаем количество человек на каждом курсе; |
|
вставляем новые данные в новую таблицу. |
Следует обратить внимание, что получение данных осуществляется не подачей команды GetData, а автоматически при каждом смещении по выборке командой Fetch.
Вставка данных осуществляется при помощи динамически формируемых запросов. Они работают медленней на 10-15%, чем запросы с параметрами, но легче в отладке – всегда можно просмотреть лог-файл ядра и понять, в чем ошибка.
Ниже представлен листинг программы из файла prac12_e3.c.
#include <stdio.h> #include <stdlib.h>
#include "linapi.h" |
|
#if defined(VXWORKS) |
/* 05.03.02 */ |
#include "vxstart.h" |
|
#endif |
|
#ifdef _BCPP_
extern unsigned _stklen = 16383;
E-mail: market@relex.ru |
ЗАО НПП «РЕЛЭКС» |
http://www.relex.ru |
|
|
|
Практическое занятие 11. Основные приемы использования LinAPI 77
#endif
/* function for error processing for LinAPI */ void processing_error(LONG ret_cod,
WORD con_id, WORD cur_id, WORD stmt_id, char * message)
{
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)) 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 < 3000)
{
/* getting string and position if syntax error is */ printf("Syntax error : line %d, position %d\n",
(short)syserr, *(short*)((char*)&syserr +2));
E-mail: market@relex.ru |
ЗАО НПП «РЕЛЭКС» |
http://www.relex.ru |
|
|
|
E-mail: market@relex.ru |
ЗАО НПП «РЕЛЭКС» |
http://www.relex.ru |
78 Практическое занятие 11. Основные приемы использования LinAPI
}
}
LINTER_CloseAPI(); /* Free library resource */ exit(1);
}
else
printf("Return code = %ld\n",ret_cod);
}
#define MAXSTRLEN 100 #define MAXKURSNUM 6
#if defined(VXWORKS) |
/* 05.03.02 */ |
|
|
MainStart(apidata, 32*1024, UninitLinterClient) |
|
||
#else |
|
|
|
int main(void) |
|
|
|
#endif |
|
|
|
{ |
|
|
|
WORD |
nConn; |
/* connection identifier */ |
|
WORD |
nCurs; |
/* cursor identifier |
*/ |
LONG |
lRet; |
/* return code */ |
|
LONG i = 0;
LONG realLen = 0;
LONG nKurs = 0;
LONG recCount = 0;
E-mail: market@relex.ru |
ЗАО НПП «РЕЛЭКС» |
http://www.relex.ru |
|
|
|
Практическое занятие 11. Основные приемы использования LinAPI 79
LONG statistic[MAXKURSNUM] = {0};
char szSQL[MAXSTRLEN * 10] = {0};
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 cursor");
if (lRet = LINTER_ExecuteDirect(nCurs, "select * from 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");
if (recCount)
{
printf("%d records selected\n", recCount);
E-mail: market@relex.ru |
ЗАО НПП «РЕЛЭКС» |
http://www.relex.ru |
|
|
|
E-mail: market@relex.ru |
ЗАО НПП «РЕЛЭКС» |
http://www.relex.ru |
80 Практическое занятие 11. Основные приемы использования LinAPI
if (lRet = LINTER_BindAnswer(nCurs, 0, 3, &nKurs, 0, 0, tInt, sizeof(nKurs), 0, 0, &realLen))
processing_error(lRet, 0, nCurs, 0,"Error BindAnswer");
for (i = 0; i < recCount; i++)
{
/* Fetch after BindAnswer gives data in nKurs*/
if (lRet = LINTER_Fetch(nCurs, toAbsNumber, i + 1, 1, 0, 0, 0))
processing_error(lRet, 0, nCurs, 0,"Error Fetch");
if (nKurs > 0 && nKurs <= MAXKURSNUM)
statistic[nKurs]++;
printf("Kurs = %d\n", nKurs);
}
}else
printf("No records found");
//create table
if (lRet = LINTER_ExecuteDirect(nCurs, "drop table PRAC12_STAT;", 0, NULL,NULL))
{
if (lRet == SQLUNKTAB)
printf("Table PRAC12_STAT not exists -- create it\n");
else
E-mail: market@relex.ru |
ЗАО НПП «РЕЛЭКС» |
http://www.relex.ru |
|
|
|