Avec un peu d'aide de Mat, j'ai pu comprendre quel était le problème, mais comme il ne l'a pas donné sous forme de réponse, je vais devoir y répondre afin qu'il puisse être partagé pour ceux qui ont le même problème, et aussi marquer comme résolu.
Donc, mon problème était que je ne pouvais pas me connecter à la base de données. Comme Mat l'a suggéré, je devrais utiliser les informations d'erreur étendues, connues sous le nom de SQLGetDiagRec
et corrigez également les arguments en fonction de la documentation. J'ai pris un moment pour apprendre comment le SQLGetDiagRec
la fonction fonctionne, mais une fois que j'ai réussi à convertir le wchar_t
en char *
J'ai pu voir l'erreur qu'il générait.
La tentative de connexion m'a donné l'erreur Data source not found and no default driver specified
. Cela m'a donné un indice, indiquant que j'ai écrit la chaîne de connexion incorrecte ou que la chaîne de texte a été mal interprétée ou mutilée.
Faire des recherches sur le net m'a donné l'idée que la chaîne était mal interprétée, et pour y remédier, j'ai dû en faire une chaîne littérale. Assez sûrement, mettre un L devant la chaîne l'a résolu !
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);
En même temps, j'ai appris à me débarrasser de l'invite, ce qui était assez facile à comprendre après avoir corrigé le problème initial. Spécifiez null pour le handle de fenêtre, définissez l'achèvement du pilote sur SQL_DRIVER_COMPLETE
et assurez-vous d'ajouter toutes les informations nécessaires dans la chaîne de connexion.
Donc, le problème suivant que j'ai eu avec la requête avec SQLExecDirect
donnait une erreur indiquant Syntax error or access violation
. Le problème était évidemment le même qu'avec la chaîne de connexion. Suffisamment
retcode = SQLExecDirect(hstmt, (SQLWCHAR*)L"SELECT TEST_STRING, TEST_INTEGER, TEST_FLOAT FROM dbo.testfire", SQL_NTS);
A fonctionné comme un charme.
Voici le code dans son intégralité, entièrement fonctionnel :
#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;
}
Cela prouve que même la plus petite chose peut tout faire échouer.
Merci Mat pour ton aide.