#c #ms-access #visual-c
Вопрос:
Мой предмет несколько глуп и сложен для меня. Я пытаюсь установить очень простое соединение с базой данных Access 2007, но соединение никогда не происходит. Я пытаюсь понять, что происходит с SQLGetDiagRec (), но программа выходит из строя при выполнении SQLGetDiagRec (). Я не так уж сильно увлекаюсь C , поэтому последние несколько дней застрял в этом. Любая помощь будет высоко оценена. Я использую Visual C 2008.
ИЗМЕНИТЬ: После изменения набора символов с Юникода на многобайтовый я смог выполнить SQLGetDiagRec. Затем я изменил два своих указателя с int и char на SQLSMALLINT и SQLCHAR, и, бам, это сработало. Спасибо большое за предупреждение, ребята.
#include "stdafx.h" #include lt;windows.hgt; #include lt;conio.hgt; #include lt;iostreamgt; #include lt;sql.hgt; #include lt;sqltypes.hgt; #include lt;sqlext.hgt; #include lt;stdio.hgt; #include lt;stdlib.hgt; int main(){ char szDSN[256] = "DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};DSN='Hospital_mdb';DBQ=C:\Hospital.mdb;"; SQLHANDLE EnvHandlePtr; SQLHANDLE ConHandle; SQLHANDLE StmtHandle; SQLRETURN rc; SQLSMALLINT iConnStrLength2Ptr; // Changing from int iConnStrLength2Ptr; SQLCHAR szConnStrOut[256]; //changing from char szConnStrOut[256]; SQLCHAR SQLState[6], Msg[SQL_MAX_MESSAGE_LENGTH]; SQLINTEGER NativeError; SQLSMALLINT MsgLen; if ( (rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, amp;EnvHandlePtr)) == SQL_SUCCESS){ printf("Environment Set!"); if( (rc = SQLSetEnvAttr(EnvHandlePtr, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_UINTEGER))==SQL_SUCCESS ){ printf("Driver Set!"); if ( (rc = SQLAllocHandle(SQL_HANDLE_DBC, EnvHandlePtr, amp;ConHandle))==SQL_SUCCESS ){ printf("Allocation Done!");//**so far, so good, but then the connection doesn't happen** rc = SQLDriverConnect(ConHandle, NULL, (SQLWCHAR*)szDSN, SQL_NTS, (SQLWCHAR*) szConnStrOut, 0, (SQLSMALLINT*) iConnStrLength2Ptr, SQL_DRIVER_NOPROMPT); if ( rc == SQL_SUCCESS ){ //if ( (rc = SQLConnect(ConHandle, (SQLWCHAR*)szDSN, SQL_NTS, (SQLWCHAR*)"", SQL_NTS, (SQLWCHAR*)"", SQL_NTS))== SQL_SUCCESS ){ printf("Connection Done"); }//end of Connection clause else{ SQLGetDiagRec(SQL_HANDLE_DBC, ConHandle, 1, (SQLWCHAR*)SQLState, amp;NativeError, (SQLWCHAR*)Msg, sizeof(Msg), amp;MsgLen); printf("Connection Failedn%s", Msg); } SQLDisconnect(ConHandle); }//end of Connection Allocation clause SQLFreeHandle(SQL_HANDLE_DBC, ConHandle); }//end of Driver clause SQLFreeHandle(SQL_HANDLE_ENV, EnvHandlePtr); }//end of Enviroment clause _getch(); }//end of main
Ответ №1:
Вы отбрасываете диагностику, которую компилятор генерирует для вашего плохого кода. По крайней мере, SQLState плох, вы передаете 6-байтовый буфер при записи 12 байтов. Это портит структуру стека. Вызов SQLDriverConnect не может работать по той же причине.
Удалите все приведения, правильно объявив свои локальные переменные.
И используйте Юникод в своем коде. Вы можете отключить его в настройках своего проекта, но это никогда не будет ошибкой, когда вы работаете с базой данных.
Комментарии:
1. В принципе, я сделал их такими из-за плохой конфигурации. После изменения набора символов проекта с Юникода на многобайтовый (и правильного объявления переменных) Я заставил его работать. Но дело в том, что я все еще не могу подключиться к базе данных, но я могу напечатать ошибку, которая является «Недопустимой строкой или длиной буфера». Я обнаружил, что это означает, что где-то здесь кроется реальная проблема
rc = SQLConnect(ConHandle, szDSN, SQL_NTS, (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"", SQL_NTS)
, спасибо за помощь, я тоже собираюсь ее найти.2. Постарайтесь не игнорировать комментарий «никогда не ошибайтесь». Юникод необходим при работе с базами данных.