Datenbank ist plötzlich schreibgeschützt (Unterschied CDatabase::Open zu OpenEx??)



  • Hallo!

    Ich nutze seit Monaten eine MSDE Datenbank per ODBC für mein Programm.
    Das funktionierte wunderbar.

    Nun habe ich letzte Woche mit dem Erstellen von ODBC Datenquellen per Quellcode experimentiert und eben musste ich feststellen, dass ich nicht mehr speichern kann.

    In der Debugausgabe steht:

    Warning: ODBC Success With Info, Changed database context to 'ad3'.
    State:01000,Native:5701,Origin:[Microsoft][ODBC SQL Server Driver][SQL Server]
    
    Changed language setting to Deutsch.
    State:01000,Native:5703,Origin:[Microsoft][ODBC SQL Server Driver][SQL Server]
    
    DBMS: Microsoft SQL Server
    , Version: 08.00.0760
    Optional feature not implemented
    State:S1C00,Native:0,Origin:[Microsoft][ODBC SQL Server Driver]
    
    Warning: Driver does not support requested concurrency.
    Optional feature not implemented
    State:S1C00,Native:0,Origin:[Microsoft][ODBC SQL Server Driver]
    

    Die letzten drei Zeilen werden immer wieder wiederholt. 😮

    Und wenn ich versuche, zu speichern kommt folgende Meldung:

    Datensatzgruppe kann nur gelesen werden.

    Ich habe wirklich nichts an meinen Recordsetklassen verändert. 😞
    Auch an den Docs und Views nicht. Alle Änderungen waren in der InitInstance.
    (Habe es extra nochmal mit Beyond Compare kontrolliert.)

    Edit: Wenn ich die Tabellen in Access verknüpfe kann ich schreiben. 😕
    Wo muss ich den Fehler denn nun suchen?
    - Datenbank direkt?
    - ODBC Eintrag?
    - CRecordset?
    - Open???? 😕 Daran habe ich nämlich was geändert... 😮

    *verzweifel* 😞

    Ooookay, ich bin einen Schritt weiter:
    So ist es schreibgeschützt:

    m_dbAd.OpenEx("DSN=meineDB;UID=sa;PWD=manager", CDatabase::noOdbcDialog);
    

    und so nicht:

    m_dbAd.Open("meineDB", FALSE, FALSE, "ODBC;UID=sa;PWD=manager");
    

    Ich möchte gerne die obere Version nutzen weil ich da den Dialog unterdrücken kann. Was muss ich da anpassen, damit ich wieder schreiben kann? 🙂



  • also bei den Datenquellen (ODBC) in der systemsteuerung kannst du auf jeden fall anklicken, dass die datenquelle schreibgeschuetzt ist, schau doch da mal nach, ob du was uebersehen hast. mehr kann ich dir grad au ned sagen.

    Esco



  • Danke für deine Antwort, aber ich bin ja mittlerweile so weit, dass es am OpenEx gelegen hat.
    Den oberen Teil vom Post habe ich nur gelassen, damit ihr wisst, wie es sich auswirkt. 🙂



  • Weiß niemand, wodran das liegt? Man muss eine Datenbank doch auch mit OpenEx öffnen können.



  • Hi,

    ich habe zwar nie mit CDatabase gearbeitet (nur mit ADO) aber mal in der MSDN
    nachgelesen.
    Laut der Dokumentation öffnet OpenEx den Dialog für die ODBC-Verbindung, falls
    nicht genügend Informationen für die Verbindung existieren. Da Du den
    Dialog unterdrückst, vermute ich, das der Connectionstring für OpenEx
    nicht ausreicht und daher die Verbindung nicht mit Schreibrecht aufgebaut wird.
    Du könntest das Flag ja mal runternehmen oder sogar CDatabase::forceOdbcDialog
    verwenden und danach mit Code mal mit GetConnect den String ausgeben lassen.
    Vielleicht kommst Du so an mehr Infos.

    Gruss
    EB



  • Also, lesen kann ich ja alle Daten. 😕

    Nur das Schreiben klappt ja nicht, aber ich gucke mal. 🙂



  • öhm 😮 :schlechtesGewissen: wegen meinem CreateDSN??
    Naja also ich öffen so:

    bool CACRSQLSet::dbOpen()
    {
    	m_db.SetLoginTimeout(DWORD(10));
    	m_db.SetQueryTimeout(DWORD(240));
    	if (!m_db.Open( _T("ACR"),FALSE,FALSE,_T("ODBC;UID=anyusr;PWD=anyusr"),false))
    		return false;
    	else
    		return true;
    }
    

    es kommt auch kein Dialog!
    Vielleicht hilft dir obiges weiter aber das einzigste was ich anders mach ist das _T( vor den Strings.



  • @EB: Mit

    m_dbAd.OpenEx("DSN=meineDB;UID=sa;PWD=manager", NULL);//CDatabase::noOdbcDialog);
    

    kann ich auch nur lesen, en Dialog kam aber nicht.

    @Polofreak:
    Neeee, du musst kein schlechtes Gewissen haben. 🙂
    Ich hatte das CreateDSN erst im Verdacht, aber jetzt habe ich es ja auf das OpenEx eingegrenzt.
    Den Dialog weglassen muss ich aber, denn der User soll da nichts eingeben können - sonst klingelt hier nur das Telefon, was da kaputt ist und ohne Dialog wäre das Problem automatisch behoben worden. 🙄
    (Der kommt ja nur, wenn das Verbinden nicht klappt.)

    Kannst du mal zum Testen folgendes machen?

    bool CACRSQLSet::dbOpen()
    {
        m_db.SetLoginTimeout(DWORD(10));
        m_db.SetQueryTimeout(DWORD(240));
        if (!m_dbAd.OpenEx("DSN=ACR;UID=anyusr;PWD=anyusr", CDatabase::noOdbcDialog))
            return false;
        else
            return true;
    }
    

    Und dann mal versuchen, irgendwas zu speichern?
    Mich würde interessieren, ob das nur auf diesem PC passiert oder immer. 🙂



  • hm ich muss mir dazu aber erst mal schnell ne DB aufm Server machen, da ich in die DB vom Tester auf gar keinen Fall schreben darf! 🙄 Haftungsausschluss und so scherze, kann also nen kleinen Moment dauern. Ich sieh aber zu dass ich es noch vor Mittag packe.



  • Immer mit der Ruhe, wenn es nicht klappt, dann suche ich so weiter. 🙂
    Sooooo wichtig ist es nicht, mach dir also keinen Ärger deswegen. ⚠



  • Hi,

    habe es mal auf die schnelle probiert und keine Probleme.
    Kann es sein, das deine DSN nicht auf die richtige Datenbank zeigt?
    Vielleicht steht die DSN ja auf die master Datenbank und der Benutzer mit dem
    du zugreifst hat deshalb kein Schreibrecht. Du kannst im Connectionstring
    nach mit angeben, welche Datenbank er verwenden soll:

    if (!m_dbAd.OpenEx("DSN=ACR;UID=anyusr;PWD=anyusr;DATABASE=MeineDB;", CDatabase::noOdbcDialog))
        if ( m_dbAd.CanUpdate() )
           TRACE(_T("Datenbankverbindung hat Schreibrecht.\n"));
    

    Gruss
    EB



  • Die DSN ist vollkommen okay. Ich muss nur die beiden Zeilen austauschen und mit Open geht es und mit OpenEx nicht.

    m_dbAd.OpenEx("DSN=meineDB;UID=sa;PWD=manager", CDatabase::noOdbcDialog);
    m_dbAd.Open("meineDB", FALSE, FALSE, "ODBC;UID=sa;PWD=manager");
    


  • Dein Problem habe ich schon verstanden. Aber Du möchtest doch herausfinden, wo
    der Unterschied liegt, oder? Was liefert denn GetConnect() für einen Connectionstring zurück, wenn du die DSN mit CDatabase::forceOdbcDialog angibst? Ist der anders als Deiner?
    Was liefert CanUpdate() zurück?
    Vielleicht sind ja auch deine ODBC-Treiber veraltet und du hast einen Bug.
    Ist MDAC 2.8 Installiert?
    Welches ist die default Datenbank in deiner DSN-Konfiguration?
    Ist es notwendig mit dem Benutzer sa (security agent) auf die Datenbank zuzugreifen?

    Also einige Stellen wo es dran liegen kann. Das es mit Open() klappt, warum
    auch immer, aber das versuchen wir ja herauszufinden 😉



  • Was EB sagt kann ich sehr gut nachvollziehen, ich hatte als StandardDB eine DB die da hieß 4862TRW wenn ich die StandardDB mit dem Open angesprochen hab (also beim Open weggelassen) dann hab ich andauernd connectiontimeouts etc bekommen, hab ich aber nicht die Standard gewählt sondern direkt 4862TRW dann gings also es lohnt sich glaube ich schon da nochmal rein zu schauen. Welche DB sprichst du denn im CreateDSN an. Da sollte am besten auch nicht einfach nur standard drin stehen denn das hat bei mir merkwürdiges verursacht auf meinem Rechner lief es so einwandfrei auf anderen gar nicht.



  • EB schrieb:

    Was liefert denn GetConnect() für einen Connectionstring zurück, wenn du die DSN mit CDatabase::forceOdbcDialog angibst? Ist der anders als Deiner?

    OpenEx mit CDatabase::noOdbcDialog:
    ODBC;DSN=ad3;UID=sa;PWD=manager;APP=Anwendung Ad3;WSID=MeinPC;DATABASE=ad3
    OpenEx mit CDatabase::forceOdbcDialog:
    ODBC;DSN=ad3;UID=sa;PWD=manager;APP=Anwendung Ad3;WSID=MeinPC;DATABASE=ad3
    Open:
    ODBC;DSN=ad3;UID=sa;PWD=manager;APP=Anwendung Ad3;WSID=MeinPC;DATABASE=ad3
    Also alle identisch. 😞

    EB schrieb:

    Was liefert CanUpdate() zurück?

    Mit Open: TRUE
    Mit OpenEx: TRUE 😕

    EB schrieb:

    Vielleicht sind ja auch deine ODBC-Treiber veraltet und du hast einen Bug.
    Ist MDAC 2.8 Installiert?

    Wie finde ich das heraus? 🙂

    EB schrieb:

    Welches ist die default Datenbank in deiner DSN-Konfiguration?

    ad3, also die, auf die ich zugreifen will.
    Die wurde angelegt mit:

    CString szDriver = "SQL Server";
    
    			CSqlConfigString arrAttributes;
    			arrAttributes.Add("DSN=ad3");
    			arrAttributes.Add("DESCRIPTION=Datenbank");
    			arrAttributes.Add("SERVER=(local)");
    			arrAttributes.Add("DATABASE=ad3");
    
    			// Sicherheitshalber löschen:
    			SQLConfigDataSource(NULL, ODBC_REMOVE_DSN, szDriver, arrAttributes);
    
    			// Jetzt erstellen
    			if (SQLConfigDataSource(NULL, ODBC_ADD_DSN, szDriver, arrAttributes))
    			{
    				m_dbAd.Open("ad3", FALSE, FALSE, "ODBC;UID=sa;PWD=manager");
    			}
    

    EB schrieb:

    Ist es notwendig mit dem Benutzer sa (security agent) auf die Datenbank zuzugreifen?

    Jein... ich war bisher zu faul, mir einen anderen User anzulegen. 😃
    Bevor ich mich mit Userrechten rumschlage habe ich noch genug andere Probleme zu lösen. 😉



  • Polofreak schrieb:

    Was EB sagt kann ich sehr gut nachvollziehen, ich hatte als StandardDB eine DB die da hieß 4862TRW wenn ich die StandardDB mit dem Open angesprochen hab (also beim Open weggelassen) dann hab ich andauernd connectiontimeouts etc bekommen, hab ich aber nicht die Standard gewählt sondern direkt 4862TRW dann gings also es lohnt sich glaube ich schon da nochmal rein zu schauen. Welche DB sprichst du denn im CreateDSN an. Da sollte am besten auch nicht einfach nur standard drin stehen denn das hat bei mir merkwürdiges verursacht auf meinem Rechner lief es so einwandfrei auf anderen gar nicht.

    Das habe ich nicht verstanden. 😕 😞
    Also, was geht und was nicht? Habe ich davon eine Sache schon gepostet? Zeig bitte mal. 🙂
    Was wäre das andere?



  • Hast schon gepostet was ich sehen wollte da wo du

    arrAttributes.add("DATABASE=
    

    machst, kannst du auch danach

    Standard

    eingeben, geht auch hin und wieder mal aber eben nicht immer. du machst es schon richtig, dass du da direkt ad3 angibst!

    Ich weiß nciht obs geht aber probiers doch mal so:

    CString szDriver = "SQL Server";
    
    			CSqlConfigString arrAttributes;
    			arrAttributes.Add("DSN=ad3");
    			arrAttributes.Add("DESCRIPTION=Datenbank");
    			arrAttributes.Add("SERVER=(local)");
    			arrAttributes.Add("DATABASE=ad3");
    
    			// Sicherheitshalber löschen:
    			SQLConfigDataSource(NULL, ODBC_REMOVE_DSN, szDriver, arrAttributes);
    
    			// Jetzt erstellen
    			if (SQLConfigDataSource(NULL, ODBC_ADD_DSN, szDriver, arrAttributes))
    			{
    				m_dbAd.Open("DSN=ad3;UID=sa;PWD=manager;DATABASE=ad3;");
    			}
    


  • Polofreak schrieb:

    Ich weiß nciht obs geht aber probiers doch mal so:

    m_dbAd.Open("DSN=ad3;UID=sa;PWD=manager;DATABASE=ad3;");
    

    Aber Open funktioniert doch. 😕
    Wieso soll ich das ändern? OpenEx geht ja nicht und als ich das DATABASE= da eingebaut habe, war es immernoch mit Schreibschutz. 😞



  • Sorry mein Fehler!
    Hm doof. Tut mir leid da kann ich dir glaub dann doch nicht mehr helfen.
    TZORRY!

    EDIT: was spricht dann gegen Open?? erscheint denn bei dir immernoch ein Dialog wenn du es wie in obigem Post machst? Du hast ja geschrieben du willst es nciht mit open weil ein Dialog kommt also bei mir kommt keiner mit Open



  • Ich habe mich nochmal etwas mit dem Problem beschäftigt.
    Leider habe ich bei mir kein Problem.

    System: Windows XP Pro / MSDE 8.00.760(SP3)

    Hier mein Zugriffcode:

    SQLConfigDataSource(NULL, ODBC_REMOVE_DSN, _T("SQL Server"), 
    		_T("DSN=ad3\0SERVER=127.0.0.1\0DATABASE=TestDB\0\0"));
    
    	VERIFY(SQLConfigDataSource(NULL, ODBC_ADD_DSN, _T("SQL Server"), 
    		_T("DSN=ad3\0SERVER=127.0.0.1\0DATABASE=TestDB\0\0")));
    
    	CDatabase db;
    	if ( db.OpenEx(_T("DSN=ad3;UID=sa;PWD=manager;DATABASE=TestDB;"), 0) )
    	{
    		if ( db.CanUpdate() )
    		{
    			TRACE(_T("Database Read/Write access.\n"));
    			CDBMember rs(&db);
    			if ( rs.Open(CRecordset::dynaset, _T("SELECT * FROM member")) )
    			{
    				while ( !rs.IsEOF() && !rs.IsBOF() )
    				{
    					if ( rs.CanUpdate() )
    					{
    						TRACE(_T("Recordset Read/Write access.\n"));
    
    						rs.Edit();
    
    						TRACE3(_T("FirstName: %s - LastName: %s - Street: %s\n"),
    							rs.m_LastName, rs.m_FirstName, rs.m_Street);
    
    						rs.m_LastName = "Mustermann";
    						rs.Update();
    					}
    
    					rs.MoveNext();
    				}
    
    				rs.Close();
    			}
    		}
    
    		db.Close();
    	}
    

    Hier mal die wichtigsten Debug-Ausgaben:

    Warning: ODBC Success With Info, Changed database context to 'TestDB'.
    State:01000,Native:5701,Origin:[Microsoft][ODBC SQL Server Driver][SQL Server]
    
    Changed language setting to us_english.
    State:01000,Native:5703,Origin:[Microsoft][ODBC SQL Server Driver][SQL Server]
    
    DBMS: Microsoft SQL Server
    Version: 08.00.0760
    ODBC Driver Manager Version: 03.52.0000
    Database Read/Write access.
    Recordset Read/Write access.
    FirstName: Mustermann
    Recordset Read/Write access.
    FirstName: Mustermann
    

    Also irgendwie fast Identisch, allerdings funktioniert es bei mir problemlos.

    CDBMember ist von CRecordset mit der Option 'dynaset' mit dem Klassenwizard
    abeleitet. Ich denke das ist bei Dir ebenfalls so.

    Um deine MDAC-Version zu prüfen, gibt es ein Tool von Microsoft allerdings
    must dein XP dafür am Genuine-Projekt teilnehmen.

    http://www.microsoft.com/downloads/details.aspx?familyid=8f0a8df6-4a21-4b43-bf53-14332ef092c9&displaylang=en

    Aktuell ist MDAC 2.8 SP1.

    Sollte über WindowsUpdate zu bekommen sein. Ansonsten das SDK oder Redistributable herunterladen.

    http://www.microsoft.com/downloads/details.aspx?FamilyID=78cac895-efc2-4f8e-a9e0-3a1afbd5922e&DisplayLang=en

    Mehr kann ich leider wohl auch nicht weiterhelfen, denn sonst scheint es
    ein Problem auf deiner Maschine zu sein.

    Gruss
    EB


Anmelden zum Antworten