Med lidt hjælp fra Mat kunne jeg finde ud af, hvad problemet var, men da han ikke gav det i form af et svar, må jeg svare på det, så det kan deles for dem, der har samme problem, og også at markere som besvaret.
Så mit problem var, at jeg ikke kunne oprette forbindelse til databasen. Som Mat foreslog, skulle jeg bruge den udvidede fejlinformation, kendt som SQLGetDiagRec
og fikser også argumenterne i henhold til dokumentationen. Det tog mig et øjeblik at lære, hvordan SQLGetDiagRec
funktionen virker, men en gang lykkedes det mig at konvertere wchar_t
til char *
Jeg var i stand til at se den fejl, det genererede.
Forbindelsesforsøget gav mig fejlen Data source not found and no default driver specified
. Det gav mig et fingerpeg, hvilket indikerede, at jeg enten skrev den forkerte forbindelsesstreng, eller at tekststrengen på en eller anden måde blev fejlfortolket eller ødelagt.
søgning på nettet gav mig indsigten i, at strengen var fejlfortolket, og for at rette op på den var jeg nødt til at gøre den til en bogstavelig streng. Sikkert nok løste det at sætte et L foran strengen!
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);
Samtidig lærte jeg at slippe af med prompten, som var ret nem at finde ud af efter at have rettet det indledende problem. Angiv null for vindueshåndtaget, indstil driverfuldførelse til SQL_DRIVER_COMPLETE
og sørg for at tilføje alle de nødvendige oplysninger i forbindelsesstrengen.
Så det næste problem, jeg havde med forespørgslen med SQLExecDirect
gav en fejl med at sige Syntax error or access violation
. Problemet var åbenbart det samme som med forbindelsesstrengen. Sikkert nok
retcode = SQLExecDirect(hstmt, (SQLWCHAR*)L"SELECT TEST_STRING, TEST_INTEGER, TEST_FLOAT FROM dbo.testfire", SQL_NTS);
Virkede som en charme.
Her er koden i sin helhed, fuldt funktionel:
#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;
}
Det viser sig bare, at selv den mindste ting kan få alt til at svigte.
Tak Mat for din hjælp.