Toon posts:

[C++] ODBC Database toegang werkt niet

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb een programma geschreven in C++, dat het aanmeldscherm moet uitvoeren (via CGI) van een toekomstig onderdeel van mijn Website. Ik was van plan de waardes die dit programma gebruikt uit te lezen uit een Database, zodat ik het programma niet hoefde te hercompileren als ik bijvoorbeeld een andere venstertitel wou.

Ik heb een Microsoft Access 97 Database gemaakt met een tabel genaam logonscreen. Deze tabel bevat de volgende waarden:
code:
1
2
3
4
5
6
7
8
9
Id1                strValue
--------------------------------------
strHTMLcmdCancel   Cancel 
strHTMLcmdSubmit   Log In 
strHTMLMainMessage Welkom 
strHTMLPass        Password 
strHTMLsrcStyle    logonscreen.css 
strHTMLTitle       C++ Test 
strHTMLUser        Username


Dit is de gebruikte (niet correct werkende) code. Ik heb echt geen idee wat er fout gaat, maar als ik het programma heb gecompileerd en hij loopt vast, krijg ik via de foutopsporing te horen dat de fout in AFXWIN.H zit.

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// Logon.cpp: Geeft het Logonscherm weer 

#include <string> 
#include <iostream> 
#include <afxdb.h> 
using namespace std; 

int main() 
{ 
    // De Database ODBC Driver specificeren 
   CString sSpecifyDriver = "MICROSOFT ACCESS DRIVER (*.mdb)"; 
    
   // De Plaats van de Database opgeven 
   CString sPathToAccessFile = "c:\\Inetpub\\executes\\main.mdb"; 
    
   // De ODBC connectie opzetten, die word uitgevoerd door de ODBC API 
   CString sDataSourceName; 
   sDataSourceName.Format("ODBC;DRIVER=%s;DSN='';Dbq=%s;", sSpecifyDriver, sPathToAccessFile);    
    
   // De database conencten/openen 
   CDatabase dbLogonScreen; 
   dbLogonScreen.Open (NULL, false, false, sDataSourceName); 
    
   CRecordset recordset(&dbLogonScreen); 
    
   // De SQL opdracht 
   CString queryString = "select * from loginscreen"; 
    
   // Zoekopdracht uitvoeren 
   recordset.Open(CRecordset::forwardOnly, queryString, CRecordset::none); 

   // Declareren van de variabellen, die daarna door databasewaarden gevuld worden 
   CString 
      strHTMLTitle, strHTMLcmdSubmit, strHTMLcmdCancel, strHTMLMainMessage, 
      strHTMLUser, strHTMLPass, strHTMLsrcStyle 
   ; 
    
   recordset.GetFieldValue("strHTMLTitle", strHTMLTitle); 
   recordset.GetFieldValue("strHTMLcmdSubmit", strHTMLcmdSubmit); 
   recordset.GetFieldValue("strHTMLcmdCancel", strHTMLcmdCancel); 
   recordset.GetFieldValue("strHTMLMainMessage", strHTMLMainMessage); 
   recordset.GetFieldValue("strHTMLUser", strHTMLUser); 
   recordset.GetFieldValue("strHTMLPass", strHTMLPass); 
   recordset.GetFieldValue("strHTMLsrcStyle", strHTMLsrcStyle); 
    
   recordset.Close( ); 

   // Header verzenden 
   cout << "header content-type: text/html\n\n"; 

   // De pagina zelf 
   cout << "<html>"; 
   cout << "<head><title>" << strHTMLTitle << "</title><link rel=\"stylesheet\" href=\"" 
      << strHTMLsrcStyle << "\" type=\"text/css\"></head>"; 
   cout << "<body><p class=\"message\">" << strHTMLMainMessage 
      << "<form method=\"post\" action=\"login.exe\">" 
      << "<table border=\"0\" width=\"100%\">" 
      << "<tr><td width=\"50%\"><p class=\"text\">" << strHTMLUser 
      << "<td width=\"50%\"><input type=\"text\" name=\"UserName\" size=\"20\"></tr>" 
      << "<tr><td width=\"50%\"><p class=\"text\">" << strHTMLPass 
      << "<td width=\"50%\"><input type=\"password\" name=\"PassWord\" size=\"20\"></tr>" 
      << "</table><p class=\"buttontext\"><input type=\"submit\" value=\"" << strHTMLcmdSubmit 
      << "\" name=\"cmsSubmit\" class=\"button\">" 
      << "<input type=\"reset\" value=\"" << strHTMLcmdCancel 
      << "\" name=\"cdmCancel\" class=\"button\">" 
      << "</form></body></html>"; 
   return 0; 
}


Ik vermoed zelf dat de fout zit in het gedeete van recordset.GetFieldValue, maar ik weet niet wat er fout aan is.

Ik gebruik Microsoft Visual C++ 6.0 (enterprise), met Microsoft Access 97 voor de database.

[ Voor 32% gewijzigd door Verwijderd op 30-06-2003 21:22 ]


Verwijderd

Leg es beter uit wat er misgaat. Loopt er iets vast of krijg je gewoon een compiler melding. Zo ja, paste deze er dan ff bij.

Verwijderd

Topicstarter
Verwijderd schreef op 30 June 2003 @ 20:47:
Leg es beter uit wat er misgaat. Loopt er iets vast of krijg je gewoon een compiler melding. Zo ja, paste deze er dan ff bij.
Ik krijg geen compiler errors meer. Deze kreeg ik wel toen CString nog gewoon string was bij de strHTML-teksten. Maar als ik het programma draait loopt ie vast en geeft hij absolut geen uitvoer. Wel geeft hij bij de foutopsporing aan dat in het volgende bestand de fout zit:
Hel gast schreef:
Dit is de gebruikte (niet correct werkende) code. Ik heb echt geen idee wat er fout gaat, maar als ik het programma heb gecompileerd en hij loopt vast, krijg ik via de foutopsporing te horen dat de fout in AFXWIN.H zit.
En hij geeft deze foutmeldingen:
afbeelding
Afbeeldingslocatie: http://www.home.zonnet.nl/familiehellings/error1.jpg

[ Voor 41% gewijzigd door Verwijderd op 30-06-2003 21:33 ]


Verwijderd

Ah een Assert dus.
Het barst in die ODBC toestand van de asserts, en waarschijnlijk om een reden. Als ik me niet vergis kun je naar de plek van de Assert springen als je op nogmaals klikt, zo niet dan moet je die afxwin1.inl (dat snap ik ff niet, moet dat niet gewoon afxwin.h zijn?) ff met de hand openen en naar line 22 gaan. Daar staat dan de assert waar ie over mekkert.
Hopelijk kun je daar dan wijs uit worden. Ik kan dit nu helaas niet nakijken, als ik morgen op m'n werk zit kijk ik nog een keer.

En ff voor de duidelijkheid, een assert is geen crash, het is een teken naar jou als programmeur: 'Je bent iets doms aan het doen'. Een assert failure is altijd een situatie waarvan de maker van een bepaalde module heeft gezegd: Dit moet je dus NIET doen.
Bijvoorbeeld jij maakt een module die een wortel uitrekent van een getal 'number', dan zou je als programmeur kunnen stellen:
ASSERT(number >= 0)

Edit: bedenk ik me net ineens. Kijk eens naar je call stack als je die assert krijgt. Kun je zien welke van de ODBC calls dit veroorzaakt.

[ Voor 10% gewijzigd door Verwijderd op 30-06-2003 22:32 ]


  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07-2025
*.inl wordt vaak gebruikt voor template 'implementations' in te zetten om alsnog een propere .h te krijgen.

Verwijderd

Topicstarter
Verwijderd schreef op 30 June 2003 @ 22:28:
......zo niet dan moet je die afxwin1.inl (dat snap ik ff niet, moet dat niet gewoon afxwin.h zijn?)......
Als ik debug kies (wat kan als je negeren pakt) dan kom ik in het bestand afxwin.h uit.

Bij deze regel:
{ ASSERT(afxCurrentResourceHandle != NULL);
return afxCurrentResourceHandle; }

En ik verwachte al dat ik iets geheel fout deed, maar ik weet bij god niet wat...

Voor de rest van de tips kijk ik morgen wel, als ik wat meer tijd heb :*)

[ Voor 8% gewijzigd door Verwijderd op 30-06-2003 23:00 ]


Verwijderd

Was het niet dat je voordat je met databases gaat werken een of andere AfxBlaatInit() moest aanroepen en als je klaar was iets van AfxBlaatTerm()?

Verwijderd

Topicstarter
Door na elke regel een regel met als code cout << "test x"; (waarbij x een oplopend getal was, na elke cout regel +1 voor x). Heb ik kunnen achterhalen dat de fout zit in het gedeelte van recordset.GetFieldValue. Deze heb ik dus allemaal vervangen door een testregel: recordset.GetFieldValue("strValue", strHTMLTitle);

Deze regel werkt wel geheel, het programm loopt niet meer vast. Maar het programma geeft onzinnige uitvoer. De waarde die strHTMLTitle heeft is namelijk '00771AEC' in plaats van 'C++ Test', of een andere tabelwaarde.

Verwijderd

Verwijderd schreef op 01 July 2003 @ 10:45:
Door na elke regel een regel met als code cout << "test x"; (waarbij x een oplopend getal was, na elke cout regel +1 voor x). Heb ik kunnen achterhalen dat de fout zit in het gedeelte van recordset.GetFieldValue. Deze heb ik dus allemaal vervangen door een testregel: recordset.GetFieldValue("strValue", strHTMLTitle);
Dat had je ook kunnen bereiken door of:
1) De stacktrace te bekijken na je Assert
2) Steppen met je debugger ;)
Deze regel werkt wel geheel, het programm loopt niet meer vast. Maar het programma geeft onzinnige uitvoer. De waarde die strHTMLTitle heeft is namelijk '00771AEC' in plaats van 'C++ Test', of een andere tabelwaarde.
Dat is easy, gebruik daarvoor de LPCTSTR operator van CString, dus:
LPCTSTR(jouwCString)

Verder:
Al die database related functies throwen excepties, die zou ik ook es gaan afvangen, als je dat niet doet, en het openen van je database of het openen van je recordset gaat mis, dan krijg je allerlei asserts bij je GetFieldValue().

Verwijderd

Topicstarter
Verwijderd schreef op 01 July 2003 @ 11:33:
[...]

Dat had je ook kunnen bereiken door of:
1) De stacktrace te bekijken na je Assert
2) Steppen met je debugger ;)


[...]

Dat is easy, gebruik daarvoor de LPCTSTR operator van CString, dus:
LPCTSTR(jouwCString)
Dank U, Hij werkt nog niet geheel correct, maar dat lukt mij zelf wel denk ik.
Verwijderd schreef op 01 July 2003 @ 11:33:
Verder:
Al die database related functies throwen excepties, die zou ik ook es gaan afvangen, als je dat niet doet, en het openen van je database of het openen van je recordset gaat mis, dan krijg je allerlei asserts bij je GetFieldValue().
Dat komt allemaal wel, dit is mijn eerste C++ programma die meer opdrachten gebruikt dan een standaard cin/cout met if, for, en while opdrachten, en hij bevind zich nu nog geheel in de testfase.

[ Voor 3% gewijzigd door Verwijderd op 01-07-2003 15:10 ]


Verwijderd

Topicstarter
Het uitezen van die database waarden lukt nu geweldig. Maar nu heb ik dus een ander probleem. Als er bij dit, door c++ gegenereerde formulier op de verzendknop gedrukt word, wil ik de verzonden waarden verwerken. Met de GET methode lukt dat wel. Hier is ook genoeg informatie over te vinden op het internet.

Maar het verzenden van wachtwoordinfo via GET vond ik niet zo'n flex idee. Daarom wou ik POST gebruiken. Dus ikke zoeken in MSDN, waar ze mij alleen willen verderhelpen als ik de plugins van IIS ga gebruiken. Tweede stap was heel voorspelbaar de GoT search... ookwel wat links, maar geeneen die echt over het maken van Formulierverwerkers gingen.

Op het internet was genoeg te vinden over CGI C++ applicaties die formulieren verwerkte, maar de helft van de links gaven niet-relevante informatie, bij de andere helft werkte de code niet, of aleen voor de GET methode...

Daarom wou ik jullie vragen hoe ik het voor elkaar krijg om die gegevens in mijn C++ programma te krijgen. Ik hoef niet te weten hoe ze verwerkt hoeven worden, dat lukt mij wel. Maar ik weet echt niet hoe ik de gegevens, verzonden via POST, mijn programma in krijg.

  • Scorpion1984
  • Registratie: Juni 2002
  • Laatst online: 14-08 14:14
Misschien c++ source from www.php.net?

Verwijderd

Topicstarter
Ik zal kijken, maar er is een reele kans dat ik daar niet uitkom... Ben nog geen super C++ programmeur

[ Voor 8% gewijzigd door Verwijderd op 04-07-2003 19:18 ]

Pagina: 1