![]() |
Datenbank: SQLite • Version: 3.5.8 • Zugriff über: ZEOS
Datenbank per Code umbenennen
Hallo zusammen,
ich versuche eine Datenbank per Code umzubenennen. Hierzu schließe ich die Datenbank per
Delphi-Quellcode:
um sie anschließend per
Db.Disconnect
Delphi-Quellcode:
umzubenennen. Dummerweise meldet Windows, das die Datei nicht umbenannt werden kann, da sie noch in Benutzung sei.
RenameFile(OldName, NewName)
Ich vermute, das das Disconnect nicht ganz ausreicht, ich möchte aber auch das Datenbankobjekt nicht freigeben / zerstören, um anschließend die Datei umzubenennen und unter dem neuen Namen wieder zu erstellen. Gibt es noch andere Möglichkeiten??? |
Re: Datenbank per Code umbenennen
Versuch mal folgendes:
1.)
SQL-Code:
2.)
RENAME DATABASE[list=1] TO <newname>;
SQL-Code:
Sonst verhindert wahrscheinlich der ganze Prozess deiner Anwendung das Umbenennen der Datenbank. In dem Falle wird dir nichts anderes übrig bleiben, als die Datenbank irgendwie vor dem Start deiner eigentlichen Anwendung umzubenennen, zB per Batch-Script.
CREATE DATABASE <newname> FROM TEMPLATE[list=1];
DROP DATABASE oldname; |
Re: Datenbank per Code umbenennen
Funktioniert leider nicht, da SQLite diese Befehle leider nicht kennt :(
|
Re: Datenbank per Code umbenennen
Ich machte so etwas ähnliches mit ZEOS + Embedded Firebird.
Da mache ich auch nur ein Disconnect dann allerdings ein CopyFile, das geht aber problemlos. Eventuell liegt es ja auch an SQLite. Das ist auf jeden Fall sehr mysteriös. Gruss Thorsten |
Re: Datenbank per Code umbenennen
Nun, an ein Kopieren der Datei habe ich auch schon gedacht, empfinde dies aber als etwas umständlicher als ein einfaches umbenennen...
... ich werde es aber trotzdem mal probieren (und wenn es nur als Zwischenlösung ist). ... funktioniert auch nicht (gleiches Ergebnis wie bei Rename) :wall: |
Re: Datenbank per Code umbenennen
Zitat:
da man ja zur Entwicklungszeit Tabellen oder Queries (manchmal auch unbewusst) aktiv schalten kann. |
Re: Datenbank per Code umbenennen
Zitat:
Im Prinzip mache ich nichts weiter als:
|
Re: Datenbank per Code umbenennen
Wie schon gesagt wird deine ganze Anwendung der Prozess sein, der den Zugriff verhindert. Vielleicht ist ZEOS oder dein SQlite Server auch nur so eingerichtet, dass sie die Datei so öffnen, dass kein geteilter Zugriff ermöglicht wird?
Daher der Vorschlag: - Anwendung erzeugt Batch, startet Batch und beendet sich selber - Batch: --- Warten, bis Anwendung wirklich zu ist --- REN[list=1] <newdb> --- Anwendung.exe - Anwendung löscht Batch |
Re: Datenbank per Code umbenennen
Zitat:
Was ZEOS oder SQLite angeht: Mir ist dort keine Einstellung bekannt, die dieses Verhalten ändert. ... Ich hab' jetzt mal ein Testprojekt aufgesetzt und siehe da es funktioniert (Ich war mir auch sicher das es vorher schonmal funktioniert hat). Stellt sich nun also die Frage warum funktioniert es nicht im eigentlichen Projekt??? :wall: Hier mal ein wenig Code und Hintergrund: Ich öffne die Datenbank so:
Delphi-Quellcode:
Definition TCatalog:
function TMasterDB.OpenCatalog(AOwner: TComponent; ACatalogName: Widestring): TCatalog;
begin Result := TCatalog.Create(AOwner, ACatalogName, '', False); if Assigned (Result) then FListedCatalogs.Add(Result); // TObjectlist (zur Verwaltung der Datenbankknoten im VST //(Anzeigeelemnent für DB und Datensätze) end;
Delphi-Quellcode:
Hier die Routine zum Umbenennen:
type
TCatalog = class(TDataModule) ConDB: TZConnection; private fCatID : Cardinal; // MasterDB-ID fCatName : WideString; // Name (VST OnGetText) fCatDescr : Widestring; // Beschreibung (VST OnHint) procedure SetCatalogID(const Value: Cardinal); procedure SetCatalogName(const Value: Widestring); procedure SetCatalogDescr(const Value: Widestring); function CreateCatalog: Boolean; public property CatalogID: Cardinal read fCatID write SetCatalogID; property CatalogName: Widestring read fCatName write SetCatalogName; property CatalogDescr: Widestring read fCatDescr write SetCatalogDescr; constructor Create(AOwner: TComponent; AName: WideString; ADesc: WideString; New: Boolean = True); overload; destructor Destroy; override; function Open: Boolean; function Close: Boolean; end; {============================================================================== Datenbankverbindung herstellen (Vorhandene DB) ===============================================================================} function TCatalog.Open: Boolean; begin Result := False; // Katalog öffnen (verbinden) with conDB do try Database := pyPathes.DBPath + fCatName + pyCatDBExt; Connect; Result := Connected; finally // end; end; {============================================================================== Datenbankverbindung schliessen ===============================================================================} function TCatalog.Close: Boolean; begin ConDB.Disconnect; Result := not ConDB.Connected; end; {============================================================================== Anlegen Neue DB ===============================================================================} function TCatalog.CreateCatalog: Boolean; var OK: Boolean; begin Result := false; OK := False; // Katalog anlegen with conDB do try Database := pyPathes.DBPath + fCatName + pyCatDBExt; Connect; with TZQuery.Create(nil) do try Connection := conDB; // Tabelle Prog internas SQL.Add('CREATE TABLE [tblInternal] ('); SQL.Add('[IntType] INTEGER NOT NULL DEFAULT 1,'); // MasterDB(0) oder Katalog(1) oder ReferenzDB(2) SQL.Add('[IntProgVersion] TEXT NOT NULL,'); // Erstellt mit Pythia Version SQL.Add('[IntDBVersion] TEXT NOT NULL,'); // Datenbankversion SQL.Add('[IntSQLVersion] TEXT NOT NULL,'); // Erstellt mit SQLite Version SQL.Add('[IntMagic] TEXT NOT NULL,'); // Magicnr der MasterDB (wird bei jedem ERZEUGEN der MasterDB neu angelegt) SQL.Add('[IntCatCreation] DATE NOT NULL,'); // Katalog erstellt am/um SQL.Add('[IntCatLastChange] DATE NOT NULL,'); // Letzte Änderungen im Katalog am/um SQL.Add('[IntCatDescr] TEXT NULL'); // Beschreibung des Katalogs SQL.Add(');'); // // Erzeugung weiterer Tabellen // // Zeitpunkt der Erstellung und Versionsnr. eintragen SQL.Add('INSERT INTO tblInternal'); SQL.Add('(IntProgVersion, IntDBVersion, IntSQLVersion, IntMagic, IntCatCreation, IntCatLastChange)'); SQL.Add(' VALUES (:AVersion, :ADBVersion, :ASQLVersion, :AMNr, DATETIME(''now''), DATETIME(''now''));'); ParamByName('AVersion').Value := pyVersion.ProgVersion; ParamByName('ADBVersion').Value := pyVersion.DBVersion; ParamByName('ASQLVersion').Value := pyVersion.SQLiteVersion; ParamByName('AMNr').Value := pyVersion.MagicNo; ExecSQL; OK := True; finally Free; end; finally // ConDB Disconnect; end; Result := OK; // Alles gut gelaufen end; {============================================================================== Erzeugen des Objektes und Anlegen des Katalogs ===============================================================================} constructor TCatalog.Create(AOwner: TComponent; AName: WideString; ADesc: WideString; New: Boolean); begin inherited Create(AOwner); fCatName := AName; fCatDescr := ADesc; if not New then Open else begin CreateCatalog; end; end; destructor TCatalog.Destroy; begin inherited Destroy; end;
Delphi-Quellcode:
Die Datenbanken (Typ TCatalog) werden über eine Objektliste verwaltet. D.h. jedesmal wenn ein TCatalogObject erzeugt wird, wird es der Objektliste FlistedCatalogs hinzugefügt. Wie oben zu sehen ist, hat jedes TCatalog auch eine Eigenschaft CatalogName, die im VST zur Anzeige benutzt wird.
function TMasterDB.RenameCatalog(ACatalog: TCatalog;
ANewCatName: Widestring): Boolean; var ACatID: Cardinal; fo, fn: WideString; begin Result := False; fo := pyPathes.DBPath + ACatalog.CatalogName + pyCatDBExt; fn := pyPathes.DBPath + ANewCatName + pyCatDBExt; // Umbenennen nur möglich wenn Verbindung getrennt // (Öffnen erst wieder bei einer Aktion am Katalog) if ACatalog.Close then begin if WideRenameFile(fo, fn) then begin // Datei erfolgreich umbenannt => auch in MasterDB umbenennen? if RenameCatalogEntry(ACatalog.CatalogID, ANewCatName) then begin ACatalog.CatalogName := ANewCatName; end else WideRenameFile(fn, fo); // Umbenennen in MasterDB fehlgeschlagen -> zurück zum ursprünglichen Namen end; end; end; Vor der Umstellung gab es keine TObjectlist, sondern nur eine StringList mit den Namen der vorhandenen DB's. Die Daten für das VST, die nun aus dem Object TCatalog kommen, kamen vorher aus Record's. Liegt vielleicht hier der Hase im Pfeffer begraben??? Klappt es wegen der Objectlist nicht??? Müsste nur 'ne Kleinigkeit am Code / Design umgestellt werden ??? Ach ja, es gibt noch eine MasterDB, in der die Namen und eine ID pro DB verwaltet werden. Aus diesem Modul kommt auch der Aufruf
Delphi-Quellcode:
RenameCatalog(ACatalog: TCatalog;
ANewCatName: Widestring) |
Re: Datenbank per Code umbenennen
Zitat:
Wer eine DB "zweimal" öffnet sollte sie auch entspr. schliessen... :duck: Daher: gelöst |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:47 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz