Einzelnen Beitrag anzeigen

Delphi.Narium

Registriert seit: 27. Nov 2017
2.415 Beiträge
 
Delphi 7 Professional
 
#6

AW: Access-Datenbank gesperrt - Problem mit Windows-Update?

  Alt 8. Okt 2020, 10:50
Hilfe, soviele Fragen und so richtig kann ich das alles nicht beantworten

Hier erstmal ein Stück Code aus 'nem Programm, das Ado nutzt und auf diverse Datenbanken zugreifen können sollen muss
Delphi-Quellcode:
  // Hier den Datenbanktypen abfragen und die Werte für Cursor ... setzen.
  // CursorLocation bei SQLite muss wohl clUseClient sein,
  // bei Access aber clUseServer
  // Hier noch testen, was bei SQLite am sinnvollsten ist.
  if fDBIsSQLite then begin
    // ctUnspecified, ctOpenForwardOnly, ctKeyset, ctDynamic, ctStatic
    // Diese Variante spart Arbeitsspeicher und ist schnell.
    // Aber es gibt keine RecNo.
    // Änderungen von Datensätzen nicht möglich.
    // con.CursorLocation := clUseServer; // Dann gibt es keine RecNo :-(
    // qrySQL.CursorType := ctKeyset;
    // qrySQL.CursorType := ctStatic;
    // Benötigt viel Arbeitsspeicher, deutlich mehr, als die Datenbankgröße.
    // Ist sehr langsam.
    qrySQL.CursorLocation := clUseClient;
    qrySQL.CursorType := ctDynamic;
    // qrySQL.CursorType := ctStatic;
    // qrySQL.CursorType := ctKeyset;
    dbckOK.ValueChecked := 'T';
    dbckOK.ValueUnchecked := 'F';
  end else
  if fDBIsAccess then begin
    qrySQL.CursorLocation := clUseServer;
    qrySQL.CursorType := ctStatic;
    dbckOK.ValueChecked := 'Wahr';
    dbckOK.ValueUnchecked := 'Falsch';
  end else
  if fDBIsFirebird then begin
    qrySQL.CursorLocation := clUseClient;
    qrySQL.CursorType := ctDynamic;
    dbckOK.ValueChecked := '1';
    dbckOK.ValueUnchecked := '0';
  end else begin
    // Ansonsten?
    qrySQL.CursorLocation := clUseClient;
    qrySQL.CursorType := ctDynamic;
    dbckOK.ValueChecked := '1';
    dbckOK.ValueUnchecked := '0';
  end;
Abhängig vom Datenbanktyp unterscheiden sich die Werte für CursorLocation und CursorType. Ohne diese Unterscheidung gibt es garantiert Fehler (zumindest auf meinen Systemen).

Da das Ganze schon ein paar Jahre alt ist, weiß ich nicht mehr so genau, wie ich zu welchen Werten kam, aber seit dem scheint es rund zu laufen.

Mein Vorgehen wäre von daher zuerst mal mit CursorLocation und CursorType zu experimentieren, bis Dein Testprogramm, das Du zweimal gestartet hast, keinen Fehler mehr wirft oder Du garantiert alle Kombinationen der beiden Eigenschaften "durchhast" und weißt, dass sie alle zu Fehlern führen.

Mit dieser Funktion baue ich mir aus meinen Programmen heraus den Connectionstring auf (sofern wahlweise auf unterschiedliche Datenbanken zugegriffen werden soll).
Delphi-Quellcode:
function fnGetDataSourceString(Handle : THandle;
                               ADOConnection : TADOConnection;
                               sConnection : String = '') : Boolean;
begin
  ADOConnection.Connected := False;
  ADOConnection.ConnectionString := PromptDataSource(handle,sConnection);
  ADOConnection.Connected := True;
  Result := ADOConnection.Connected;
end;
Was kommt bei Deinem Testprogramm dabei raus? Stimmt das mit dem von Dir selbst erstellten Connectionstring überein oder mit dem vom Assistenten generierten? Bei meinen System stimmt es eher mit Deinem (im vorherigen Post) selbst erstellten Connectionstring überein.

Hier ein Beispiel:
Code:
Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;Data Source=C:\Support\TipVerwaltung.mdb;Mode=Share Deny None;Extended Properties="";Jet OLEDB:System database="";Jet OLEDB:Registry Path="";Jet OLEDB:Database Password="";Jet OLEDB:Engine Type=5;Jet OLEDB:Database Locking Mode=1;Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Global Bulk Transactions=1;Jet OLEDB:New Database Password="";Jet OLEDB:Create System Database=False;Jet OLEDB:Encrypt Database=False;Jet OLEDB:Don't Copy Locale on Compact=False;Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=False
Querys werden bei mir nach Gebrauch sofort per Close geschlossen. Allerdings erstelle ich sie nicht dynamisch, sondern hab' sie gewöhnlich auf 'nem TDataModule, auch wenn es da durchaus mal eine ganze Reihe für unterschiedliche Zwecke geben kann.

Zur Reihenfolge:

Weise bitte zuerst den Connectionstring zu und ändere erst dann (soweit erforderlich) die Eigenschaften der ADOConnection. Ich gehe mal davon aus, dass die von Dir gesetzten Werte beim Setzen des Connetionstring "überschrieben" werden. Machst Du die Änderungen nach der Zuweisung des Connectionstrings, werden "seine" Werte durch Deine überschrieben. Damit wärst Du dann quasi der Gewinner. So, wie Du es momentan zu machen scheinst, gewinnt jedoch der Connectionstring.

Als erste Idee (ohne Garantie für irgendwas):
Delphi-Quellcode:
    db.Close;
    db.ConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0;'
                       + 'User ID=Admin;'
                       + 'Data Source=' + _FileName + ';'
                       + 'Mode=Share Deny None;'
                       + 'Jet OLEDB:System database="";'
                       + 'Jet OLEDB:Registry Path="";'
                       + 'Jet OLEDB:Database Password="";'
                       + 'Jet OLEDB:Engine Type=5;'
                       + 'Jet OLEDB:Database Locking Mode=1;'
                       + 'Jet OLEDB:Global Partial Bulk Ops=2;'
                       + 'Jet OLEDB:Global Bulk Transactions=1;'
                       + 'Jet OLEDB:New Database Password="";'
                       + 'Jet OLEDB:Create System Database=False;'
                       + 'Jet OLEDB:Encrypt Database=False;'
                       + 'Jet OLEDB:Don''t Copy Locale on Compact=False;'
                       + 'Jet OLEDB:Compact Without Replica Repair=False;'
                       + 'Jet OLEDB:SFP=False;'
                       + 'Persist Security Info=False;';
    db.KeepConnection := True; // HAL_Registry_GetBool('KeepConnection', True);
    db.LoginPrompt := False;
    db.CursorLocation := clUseServer;
    db.CursorType := ctStatic;
    db.IsolationLevel := ilReadCommitted;
    db.Mode := cmReadWrite;

    c1 := db.ConnectionString;
    db.Open;
    c2 := db.ConnectionString;
Damit scheinen bei mir mehrere Instanzen eines Programmes problemlos mit einer Accessdatenbank arbeiten zu können.
  Mit Zitat antworten Zitat