Strategiefrage: Eine DB-Verbindung für ALLE Datenbankabfragen (Zeitfaktor und wie?)
-
Hm, dann ist dein Zeiger ungültig.
Versuchs mal mit einem Gültigen Zeiger auf eine gültige
Instanz von CRecordset.Devil
-
@devil81: Schon versucht die STL in eine DLL zu packen?
Ich schon und es ging nicht sodaß keine Abhängigkeiten mehr da sind.
-
devil81 schrieb:
Hm, dann ist dein Zeiger ungültig.
Versuchs mal mit einem Gültigen Zeiger auf eine gültige
Instanz von CRecordset.Aber das ist doch ein Zeiger auf CDatabase, den ich dem Konstruktor von CRecordset erst übergebe - da habe ich doch noch keine Instanz vom Recordset.
-
estartu_de schrieb:
devil81 schrieb:
Hm, dann ist dein Zeiger ungültig.
Versuchs mal mit einem Gültigen Zeiger auf eine gültige
Instanz von CRecordset.Aber das ist doch ein Zeiger auf CDatabase, den ich dem Konstruktor von CRecordset erst übergebe - da habe ich doch noch keine Instanz vom Recordset.
Die Frage ist doch, ob der Zeiger zu dem Zeitpunkt schon/noch gültig ist,
oder ob er überhaupt gültig ist. Dein C-Cast da stellt doch garnicht sicher,
das überhaupt eine Instanz der Klasse dort korrekt existiert.Devil
-
Okay, ich habs jetzt ordentlich gemacht:
CBasisSet::CBasisSet(CString f_strTabelle) : CRecordset((dynamic_cast<CAd3App*>(AfxGetApp()))->GetDb())
Funktioniert aber trotzdem nicht.
Der Zeiger auf die App ist okay, und die CDatabase-Instanz sieht soweit ich das im Debugger erkennen kann auch gut aus.Warum setzt der trotzdem alles auf ReadOnly?
Achja, damit du dir auch das Erstellen der Verbindung mal angucken kannst:
BOOL CAd3App::InitInstance() { // InitCommonControls() ist für Windows XP erforderlich, wenn ein Anwendungsmanifest // die Verwendung von ComCtl32.dll Version 6 oder höher zum Aktivieren // von visuellen Stilen angibt. Ansonsten treten beim Erstellen von Fenstern Fehler auf. InitCommonControls(); if (!m_dbAd.OpenEx("DSN=audiodatic;UID=sa;PWD=manager", CDatabase::noOdbcDialog)) { CLog::Melde(_T("Es konnte keine Verbindung mit der Datenbank hergestellt werden, das Programm wird beendet.")); return FALSE; } // Anmeldedialog anzeigen CAnmeldeDlg dlg(m_rBenutzer); // Erst nach dieser Zeile kommen die ersten Datenbankzugriffe. [...]
-
Hm, it a feature, not a bug
vielleicht hilft CDatabase::noOdbcDialog| ~CDatabase::ReadOnly *g*
Hast du es schon mal mit Open versucht ?
Seh gerade das Readonly könnte man im Recordset mit einem Open evtl. wieder aus
der Welt schaffen, falls die Database und MS das zuläst.Devil
-
devil81 schrieb:
vielleicht hilft CDatabase::noOdbcDialog| ~CDatabase::ReadOnly *g*
Args, du grinst extra noch und ich Horsti probiers trotzdem aus.
Nein, das funktioniert jedenfalls überhaupt nicht.devil81 schrieb:
Seh gerade das Readonly könnte man im Recordset mit einem Open evtl. wieder aus
der Welt schaffen, falls die Database und MS das zuläst.Ich mach doch für jedes Recordset noch ein Open - oder was meinst du jetzt?
Sorry, ich stehe heute und besonders bei Datenbankzeugs total auf dem Schlauch...So sieht meine Funktion aus, mit der ich JEDES Recordset öffne:
try { if(!IsOpen()) { fResult = Open(); } else { fResult = Requery(); } } catch (CDBException* e) { CLog::Log(LOG_NR_DB_FEHLER, e->m_strError); throw(e); // Weiterwerfen }
Ich sehe bei der Hilfe zu Open aber nichts, was mit ReadOnly oder dessen Aufhebung zu tun hat.
Jetzt gucke ich mal, ob der Tausch von OpenEx (das fand ich wegen der geringen Parameteranzahl sympatisch) gegen Open was hilft.
-
Schau dir mal den MSDN Artikel zu CRecordset::Open an.
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_crecordset.3a3a.crecordset.aspIch hab keine ahnung was AFX_DB_USE_DEFAULT_TYPE für einen wert hat,
evtl. musst du da CRecordSet::dynaset oder so hinmachen. ReadOnly könnte Default seinDevil
-
Es lag am OpenEx.
Ich mache das jetzt so:if (!m_dbAd.Open("audiodatic", FALSE, FALSE, "ODBC;UID=sa;PWD=manager"))
Und momentan gibt es keine offensichtlichen Probleme...
Wie schon gesagt: Von den Möglichkeiten bei CRecordset::Open schien keine zu passen:
CRecordset::dynaset
CRecordset::snapshot
CRecordset::dynamic
CRecordset::forwardOnlyDer default hatte ja funktioniert und funktioniert jetzt wieder.
Aber vielen Dank fürs geduldige Ausdiskutieren.
Hast du vielleich noch nen Zusatztip, wo man leicht verständliche Tutorials zur fehlersicheren Datenbanknutzung bekommt?
Ich bin bisher dank "Unverständnis" doch äußerst sparsam mit try...catch.Da muss es doch auch irgendwo eine Anleitung geben, oder?
-
Alles was schiefgehen kann sollte einen Try Catch Block haben
Dann musst du aber auch noch die richtige Exception fangen.
Für den Anfang dürfte aber in der MFC CException zu fangen reichen.Jens
-
Okay, DAS muss man dann aber von Anfang an ordentlich machen oder sorgfältig nachbessern. *graus*
So eine Lösung wie "überschreib die und die und die Funktionen in den und den Klassen und dann hast du soundsoviel Prozent erschlagen" gibts wohl nicht, oder?
Irgendwann raff ich das auf noch... *hoff*
-
Naja du kannst versuchen es möglichs hoch selber anzusetzen, geht bei Updates/Inserts/Deletes auch wunderbar, macht man eine RunSQL-Methode oder sowas und hat dann einmal Try/Catch(CDBException) und fängt eigentlich alle Datenbank-Fehler ab, also falsche SQL-Syntax, verstöße gegen constraints, Tablespace voll etc..)
Bei selects ist das nur bischen umständlicher, weil die ja immer eine unterschiedliche Rückgabe haben. Da klammere ich Momentan noch die ganze Methode in einen try-block. Man könnte es aber bestimmt auch schaffen das Ergebnis der select gleich als Array zu speichern. Dynaset fällt dann natürlich flach..
-
Es gibt die Lösung also doch.
Fein, dann kann ich das ja mal einbauen.