Sie sind nicht angemeldet.

MAX

Senior Schreiberling

  • »MAX« ist männlich
  • »MAX« ist der Autor dieses Themas

Beiträge: 822

Registrierungsdatum: 11.12.2001

Wohnort: Hannover

1

23.06.2004, 18:43

C++, MFC, Access Problem

Hallo!
Problem:
In C++ mit Hilfe von MFC habe ich eine Klasse mit Datenbankzugriff schreiben müssen. Als Datenbank wird Access eingesetzt. Ich habe also meine Klasse von der CRecordset abgeleitet. Die Methode void DoFieldExchange(CFieldExchange* pFX); überschrieben, damit man auf die einzelne Datensätze zugreifen kann und entsprechende Variablen zum Abspeichern der Werte derklariert. Hier ein Codeschnipsel des Datenbankzugriffes:

Quellcode

1
2
3
4
5
6
CDatabase db;
db.Open("MeineDatenbank");
MyRecordset rs(&db);
rs.Open(MyRecordset::snapshot, "SELECT Argument FROM Tabelle", MyRecordset::none);
rs.Close();
db.Close();

So das wäre die Vorgehensweise so zu sagen. Das Problem tritt beim rs.Open(...) auf. Ich bekomme hier eine CDBException. Das error Objekt meldet mir: "Üngültiger Deskriptorindex"
Mit der Meldung kann ich überhaupt nichts anfangen. Ich habe in das Objekt reingeschaut und das Argument m_strStateNativeOrigin hat folgenden Inhalt: {"State:S1002,Native:0,Origin:[Microsoft][ODBC Cursor Library]
"}
In der MSDN habe ich nach dem Fehler S1002 gesucht und folgendes gefunden:

Zitat


SQLSTATE Mappings
In ODBC 3.x, HYxxx SQLSTATEs are returned instead of S1xxx, and 42Sxx SQLSTATEs are returned instead of S00XX. This was done to align with X/Open and ISO standards. In many cases, the mapping is not one-to-one because the standards have redefined the interpretation of several SQLSTATEs.

When an ODBC 2.x application is upgraded to an ODBC 3.x application, the application has to be changed to expect ODBC 3.x SQLSTATEs instead of ODBC 2.x SQLSTATEs. The following table lists the ODBC 3.x SQLSTATEs that each ODBC 2.x SQLSTATE is mapped to.

When the SQL_ATTR_ODBC_VERSION environment attribute is set to SQL_OV_ODBC2, the driver posts ODBC 2.x SQLSTATEs instead of ODBC 3.x SQLSTATEs when SQLGetDiagField or SQLGetDiagRec is called. A specific mapping can be determined by noting the ODBC 2.x SQLSTATE in column 1 of the following table that corresponds to the ODBC 3.x SQLSTATE in column 2.
...
S1002 07009 ODBC 2.x SQLSTATE S1002 is mapped to ODBC 3.x SQLSTATE 07009 if the underlying function is SQLBindCol, SQLColAttribute, SQLExtendedFetch, SQLFetch, SQLFetchScroll, or SQLGetData.


und

Zitat


FIX: Assertion Failure in CFieldExchange::GetColumnType()
Last reviewed: September 25, 1997
Article ID: Q135666
The information in this article applies to:
The Microsoft Foundation Classes (MFC) included with: - Microsoft Visual C++, 32-bit Edition, versions 2.0, 2.1, 2.2, 4.0,

4.1, 4.2




SYMPTOMS
Using the MFC database classes with the Microsoft SQL Server ODBC driver versions 2.50.0121 or 2.50.0126 may cause an assertion failure after a call to SQLNumResultCols() in the CFieldExchange::GetColumnType() function.



CAUSE
This error is caused by a bug in the ODBC driver that is exposed when the cursor library is used, and happens after calling CRecordset::Requery() and then trying to edit more than one record.

The following code in Dbrfx.cpp produces the assertion:

#ifdef _DEBUG

SWORD nResultColumns;
AFX_SQL_ASYNC(m_prs,
::SQLNumResultCols(m_prs->m_hstmt, &nResultColumns));
ASSERT(nColumn >= 1 && (long)nColumn <= (long)nResultColumns);

#endif //_DEBUG
::SQLNumResultCols returns 0 in nResultColumns, which causes an assertion on the next line. This is due to a bug in the driver which sets the number of columns in the result set to 0. The subsequent call to ::SQLDescribeCol will also fail with SQL State S1002 "Invalid Column number" regardless of the column number specified.



RESOLUTION
To work around this problem, use a dynaset instead of a snapshot or get the 2.65.0240 version of the SQL Server driver that is included with Visual C++ 5.0.



STATUS
Microsoft has confirmed this to be a bug with the ODBC 2.5 components. This bug has been fixed in the 2.65.0240 version of the SQL Server driver that is included with Visual C++ 5.0.




dynaset hat bei mir nicht funktioniert. Ich habe wieder eine Exception bekommen, die mir mitteilte, dass dynaset nicht unterstützt wird. Ehrlich gesagt weiß ich nicht woher ich diesen Treiber im System finde und wie ich ihn aktualisieren kann. Auf Microsofts Seiten habe ich bisher auch nichts gefunden. Kennt sich damit jemand aus? Oder hat eine Lösung parat?
mfg
MAX

PS: Ich benutze MS Visual C++ 6.0

dfex

Junior Schreiberling

  • »dfex« ist männlich

Beiträge: 248

Registrierungsdatum: 11.12.2001

2

24.06.2004, 18:17

RE: C++, MFC, Access Problem

Ok, ich kann jetzt nicht so viel dazu sagen, weil ich mich mit c++ nich so gut auskenne .. aber der Zugriff über ODBC in C++ sollte doch recht einfach sein. Und nen DSN kannst du auch für MS Access Datenbanken anlegen.


Vielleicht hilft dir ja dieses Bsp.:
http://msdn.micros..._sample_mfc_ENROLL.asp

Da gehts zumindest auch um DB Zugriff über ODBC mit MFC. Vielleicht kannste da ja was abgucken.

MAX

Senior Schreiberling

  • »MAX« ist männlich
  • »MAX« ist der Autor dieses Themas

Beiträge: 822

Registrierungsdatum: 11.12.2001

Wohnort: Hannover

3

24.06.2004, 19:49

Hat sich schon erledgt!
Das Problem war mir völlig unbekannt. Und bei der Lösung war ich ein bißchen enttäuscht von der Klasse CRecordset.
Der Datenbankzugriff mittels ODBC ist wirklich einfach. ABER das blöde ist, dass man für jede Tabelle, die man anlegt eine eigene Klasse abgeleitet von CRecordset schreiben muss. Ok das erledigt noch der MFC Assistent. Will man aber etwas kompliziertere Anfragen stellen, mit JOINs, dann müsste man auch eigene Klasse dafür schreiben oder ein wenig tricksen. So habe ich zumindestens in der MSDN gefunden. Für mich war das etwas enttäuschend. Wenn jemand eine bessere Lösung kennt, dann wäre es nicht schlecht, wenn er/sie hier reinposten würde.
mfg
MAX