Met een beetje hulp van Mat kon ik erachter komen wat het probleem was, maar aangezien hij het niet in de vorm van een antwoord gaf, zal ik het moeten beantwoorden zodat het kan worden gedeeld voor degenen die de hetzelfde probleem, en ook markeren als beantwoord.
Dus mijn probleem was dat ik geen verbinding kon maken met de database. Zoals Mat suggereerde, zou ik de uitgebreide foutinformatie moeten gebruiken, bekend als SQLGetDiagRec
en corrigeer ook de argumenten volgens de documentatie. Het kostte me even om te leren hoe de SQLGetDiagRec
functie werkt, maar toen ik erin slaagde de wchar_t
. te converteren naar char *
Ik kon de fout zien die het genereerde.
De verbindingspoging gaf me de fout Data source not found and no default driver specified
. Dat gaf me een aanwijzing dat ik ofwel de verkeerde verbindingsreeks had geschreven of dat de tekstreeks op de een of andere manier verkeerd was geïnterpreteerd of verminkt.
Wat zoeken op internet gaf me het inzicht dat de string verkeerd werd geïnterpreteerd, en om het te repareren moest ik er een letterlijke string van maken. Inderdaad, een L voor de string plaatsen loste het op!
retcode = SQLDriverConnect(hdbc, 0,
(SQLWCHAR*)L"DSN=TestConnection;SERVER=localhost;UID=user;PWD=password;DRIVER=MySQL Server;",
_countof(L"DSN=TestConnection;SERVER=localhost;UID=user;PWD=password;DRIVER=MySQL Server;"),
OutConnStr, 255, &OutConnStrLen, SQL_DRIVER_COMPLETE);
Tegelijkertijd leerde ik hoe ik van de prompt af kon komen, wat vrij eenvoudig te achterhalen was na het corrigeren van het oorspronkelijke probleem. Geef null op voor de vensterhandle, stel de voltooiing van het stuurprogramma in op SQL_DRIVER_COMPLETE
en zorg ervoor dat u alle benodigde informatie toevoegt aan de verbindingsreeks.
Dus het volgende probleem dat ik had met de query met SQLExecDirect
gaf een foutmelding met de melding Syntax error or access violation
. Het probleem was duidelijk hetzelfde als met de verbindingsreeks. Zeker genoeg
retcode = SQLExecDirect(hstmt, (SQLWCHAR*)L"SELECT TEST_STRING, TEST_INTEGER, TEST_FLOAT FROM dbo.testfire", SQL_NTS);
Werkte als een zonnetje.
Hier is de code in zijn geheel, volledig functioneel:
#include <iostream>
#include <windows.h>
#include <sql.h>
#include <sqltypes.h>
#include <sqlext.h>
#include <string>
using namespace std;
int main(){
SQLHENV henv;
SQLHDBC hdbc;
SQLHSTMT hstmt;
SQLRETURN retcode;
SQLWCHAR OutConnStr[255];
SQLSMALLINT OutConnStrLen;
// Allocate environment handle
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
// Set the ODBC version environment attribute
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
// Allocate connection handle
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
// Set login timeout to 5 seconds
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);
// Connect to data source
retcode = SQLDriverConnect(
hdbc,
0,
(SQLWCHAR*)L"DSN=TestConnection;SERVER=localhost;UID=root;PWD=never140;DRIVER=MySQL Server;",
_countof(L"DSN=TestConnection;SERVER=localhost;UID=root;PWD=never140;DRIVER=MySQL Server;"),
OutConnStr,
255,
&OutConnStrLen,
SQL_DRIVER_COMPLETE );
// Allocate statement handle
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
// Process data
retcode = SQLExecDirect(hstmt, (SQLWCHAR*)L"SELECT TEST_STRING, TEST_INTEGER, TEST_FLOAT FROM dbo.testfire", SQL_NTS);
if (retcode == SQL_SUCCESS) {
SQLINTEGER sTestInt, cbTestStr, cbTestInt, cbTestFloat, iCount = 1;
SQLFLOAT dTestFloat;
SQLCHAR szTestStr[200];
while (TRUE) {
retcode = SQLFetch(hstmt);
if (retcode == SQL_ERROR || retcode == SQL_SUCCESS_WITH_INFO) {
cout<<"An error occurred";
}
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO){
SQLGetData(hstmt, 1, SQL_C_CHAR, szTestStr, 200, &cbTestStr);
SQLGetData(hstmt, 2, SQL_C_ULONG, &sTestInt, 0, &cbTestInt);
SQLGetData(hstmt, 3, SQL_C_DOUBLE, &dTestFloat, 0,&cbTestFloat);
/* Print the row of data */
cout<<"Row "<<iCount<<":"<<endl;
cout<<szTestStr<<endl;
cout<<sTestInt<<endl;
cout<<dTestFloat<<endl;
iCount++;
} else {
break;
}
}
}else{
cout<<"Query execution error."<<endl;
}
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
SQLDisconnect(hdbc);
}else{
cout<<"Connection error"<<endl;
}
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
}
}
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
system("pause");
return 0;
}
Het laat maar zien dat zelfs het kleinste ding alles kan doen mislukken.
Bedankt Mat voor je hulp.