Возник такой вопрос. В БД (Access 2000) заносятся записи со скоростью приблизительно 8 записей в секунду (+- 3 записи). Записи успешно добавляются, вот код для их добавления
char *szQueryY="INSERT INTO `Y_Table` (`Num`,`WorkTime`,`Y`) VALUES (?,?,?);";
char *szQueryI="INSERT INTO `I_Table` (`Num`,`WorkTime`,`I`) VALUES (?,?,?);";
char *szQuery;
switch(table)
{
case 'Y':szQuery=szQueryY; break;
case 'I':szQuery=szQueryI; break;
default: return false;
}
SQLPrepare(hstmt, (UCHAR*)szQuery, SQL_NTS);
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_INTEGER,
SQL_INTEGER, 1, 0, &Num, 0, 0);
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_DOUBLE,
SQL_C_DOUBLE, 1, 0, &Time, 0, 0);
SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_DOUBLE,
SQL_C_DOUBLE, 1, 0, &mean, 0, 0);
if(SQLExecute(hstmt)==SQL_ERROR)
{
return false;
}
return true ;
}
Как я сказал, записи добавляются успешно. Но я немного лукавлю. Есть проблема, время от времени SQLExecute() возвращает SQL_ERROR. При этом входные данные подаются корректные (т.е. практически ничем не отличаются от тех, на которых SQL_Execute нормально отрабатывала). Никакой закономерности по времени и по входным данным не обнаружено. Т.е. я не могу сказать, что каждые 2 минуты происходит ошибка или при каких-то определенных значениях. Но я могу сказать, что чем дольше работает прога, тем ошибки появляются чаще. У меня складывается ощущеие, что это зависит от размера БД. Чем больше в ней записей, тем чаще ошибки. Если БД почистить, то некоторое время ошибки не выскакивают, но потом постепенно появляются, при этом как я говорил частота их появления возрастает.
Если БД не обнулять, но закрыть приложение, а потом опять запустить, то ошибки начинают выскакивать практически сразу (что косвенно подтверждает зависимость их появления от размеров БД)
У меня 2 вопроса:
1) Почему это происходит? Кто(что) в этом виноват?
2) Как с этим бороться? (Что делать? -Чернышевский).
Я пробовал подставить такой запрос
INSERT INTO `Y_Table` (`Num`,`WorkTime`,`Y`) VALUES (1,1,1);";
INSERT INTO `I_Table` (`Num`,`WorkTime`,`I`) VALUES (2,2,2);
Но ошибки все равно, время от времени выскакивали, что еще раз подтверждает, что дело не во входных даны.
Пробовал транзакции – добавлял в конце функции
SQLTransact(henv,hdbc,SQL_COMMIT);
Не помогло. Кстати эта функция нужна там или нет?
У меня есть на примете одно решение:
В случае, если запрос не удался делать Sleep() на 10-50мс и повторить запрос. Так до тех пор, пока запрос не проскочит, но не более 5 раз (к примеру, а то может и 2 или 10).
Но хотелось бы более элегантно решить эту проблему. К тому же попытка повторить запрос не гарантирует успех, т.к. уже пробовал повторять запрос второй раз в случае неудачи и бывало, что и второй раз подряд выскакивала ошибка.
Итак, работа происходит с БД – Microsoft Access 2000, используется ODBC (ну, я думаю, все догадались).
На всякий случай опишу структуру БД (а именно 2 таблицы, т.к. только в них трабблы):
№ Имя Тип
I_Table
1) Num счетчик (автоинкремент) Длинное целое
2) WorkTime Длинное целое
3) I Действительное
Y_Table
1) Num счетчик (автоинкремент) Длинное целое
2) WorkTime Действительное
3)Y Двойное с плавающей точкой
Структура БД не обсуждается

.
Заранее спасибо за развернутые ответы.
P.s. Забыл написать как подключаюсь, мало ли пригодится
Codbc::Codbc()
{
//////////////
szUser[256] = 0;
szPass[256] = 0;
strcpy(szDsn,"mysource");
hstmt=NULL;
henv = NULL;
hdbc = NULL;
/////////////
if (::SQLAllocHandle(SQL_HANDLE_ENV, NULL, &henv) == SQL_ERROR)
{
MessageBox(0,"error connect","error connect",0);
}
::SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,
(void*) SQL_OV_ODBC3, SQL_IS_INTEGER);
if ( ::SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc) == SQL_ERROR)
{
MessageBox(0,"error connect2","error connect2",0);
}
if ( ::SQLConnect(hdbc, (SQLTCHAR*)szDsn, SQL_NTS,
(SQLTCHAR*)szUser, _tcslen(szUser), (SQLTCHAR*)szPass,
_tcslen(szPass) ) == SQL_ERROR )
{
MessageBox(0,"error connect source","error connect source",0);
}
if (::SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt) == SQL_ERROR)
{
MessageBox(0,"Error zapros","Error zapros",0);
}
}