Registriert seit: 4. Nov 2005
Ort: Basel
442 Beiträge
Delphi XE2 Enterprise
|
Datenbank ( Tabellen ) Aktualisierung
12. Aug 2010, 18:13
Datenbank: Firebird • Version: 2.1 • Zugriff über: Fibplus
Hallo zusammen
vor längerer Zeit habe ich hier im Forum Bsp. gefunden um eine DB zu aktualisieren. ( Leider weiss ich nicht mehr von wem / Hatte es im alten Forum in den "gespeicherten Themen" die sind nun aber leider weg.. )
Folgendes ist der Fall:
Tabelle in der DB:
Code:
SELECT
ID,
DB_DATE,
MAJOR,
MINOR,
REL,
BUILD,
SCRIPT,
RUNNED,
CAST(CAST(MAJOR AS BIGINT)*1000000000+MINOR*1000000+REL*1000+BUILD AS BIGINT) AS VERSION
FROM
G_DB_VERSION
WHERE MAJOR < :MAJOR1 OR (MAJOR = :MAJOR2 AND (MINOR < :MINOR1 OR (MINOR = :MINOR2 AND (REL < :RELEASE1 OR (REL = :RELEASE2 AND (BUILD <= :BUILD))))))
ORDER BY RUNNED DESC, MAJOR, MINOR, REL, BUILD
Überprüfung der Version:
Delphi-Quellcode:
procedure TDM_update.CheckDBVersion;
var
AskFirst : boolean ;
LastRunned, v, NV : int64 ;
NeedRestart, BackupOK : boolean ;
begin
dm.DB_Gideons.Connected:= true;
FI.Filename := application.exename ;
v := FI.Version.Major*1000000000 + FI.Version.Minor*1000000 +
FI.Version.Release*1000 + FI.Version.Build ;
//showmessage (inttostr(v)) ;
AskFirst := true ;
// AskFirst := false ;
SkriptError := false ;
NeedRestart := false ;
UpdateVersionTableRecords ;
with sqlVersion do
begin
close ;
parambyname ('Major1').AsInteger := FI.Version.Major ;
parambyname ('Minor1').AsInteger := FI.Version.Minor ;
parambyname ('Release1').AsInteger := FI.Version.Release ;
parambyname ('Major2').AsInteger := FI.Version.Major ;
parambyname ('Minor2').AsInteger := FI.Version.Minor ;
parambyname ('Release2').AsInteger := FI.Version.Release ;
parambyname ('Build').AsInteger := FI.Version.Build ;
open ;
if Locate ('RUNNED',1,[]) then
begin
// if Locate ('RUNNED',1,[]) then begin
{ Blättern bis letzen Runned=true gefunden. Dann weiter bis Runned=false }
{ jedoch Version > LastRunned }
ID := -1 ;
LastRunned := 0 ;
repeat
if FieldByName ('Runned').AsBoolean
then LastRunned := FieldByName ('Version').asInteger ;
if not FieldByName ('Runned').AsBoolean
then ID := FieldByName ('ID').AsInteger ;
if not EOF then next ;
until EOF or (ID <> -1) ;
if ID <> -1 then begin
Locate ('ID',ID,[]) ;
ID := FieldByName ('ID').AsInteger ;
NV := FieldByName('Version').AsInteger ;
while (not EOF) and (NV < LastRunned) do begin
ID := -1 ;
next ;
if not eof then begin
NV := FieldByName('Version').AsInteger ;
ID := FieldByName ('ID').AsInteger ;
end ;
end ;
Locate ('ID',ID,[]) ;
end ;
end else
begin
{ Einfacher Fall: Alle Skripte ausführen }
First ;
ID := FieldByName ('ID').AsInteger ;
end ;
//showmessage ('Entgültige ID: ' + inttostr(ID)) ;
while (not EOF) and (not SkriptError) and (not FieldByName('Runned').AsBoolean) and (ID <> -1) do begin
if AskFirst
then if MessageDlg('Datenbankskripte ausführen ?', mtConfirmation, [mbYes, mbNo], 0) = mrYes
then
begin
case MessageDlg('Soll vor der Ausführung der Skripte ein Datenbank Backup erfolgen?', mtConfirmation, [mbYes, mbNo, mbAbort], 0) of
mrYes : if not (MakeBackup) then
begin
close ;
exit ;
end ;
mrAbort :
begin
close ;
exit ;
end ;
end ;
NeedRestart := true ;
DM.DB_Gideons.Close;
DM.DB_Gideons.Open ;
Open ;
Locate ('ID',ID,[]) ;
AskFirst := false ;
end
else begin
close ;
exit ;
end ;
// Backup wird in jedem Fall durchgeführt
MakeBackup;
//
// MessageDlg(sqlVersion.SelectSQL.Text, mtInformation, [mbOK], 0);
// hier tritt der Fehler auf:
RunDBScript (FieldByName('Major').AsInteger,
FieldByName('Minor').AsInteger,
FieldByName('Rel').AsInteger,
FieldByName('Build').AsInteger) ;
next ;
end ;
close ;
end ;
if NeedRestart then begin
MessageDlg('Die Anwendung muss nun neu gestartet werden.', mtInformation, [mbOK], 0);
// shellexecute (frm_main.handle,'open',PChar(application.exename),'',PChar(ExtractFilePath(application.exename)),SW_SHOWNORMAL) ;
application.terminate ;
end ;
end;
Ausführen des Updates aus einer sql Datei:
Delphi-Quellcode:
procedure TDM_update.RunDBScript (Major,Minor,Release,Build : integer) ;
var
V, Filename : string ;
begin
V := format('v.%d.%d.%d.%d',[Major,Minor,Release,Build]) ;
frm_ScriptProgress := Tfrm_ScriptProgress.create (Self) ;
with frm_ScriptProgress do
begin
lblVersion.caption := V ;
PB.Position := 0 ;
Filename := ScriptsDir + V + '.txt' ;
show ;
if FileExists (Filename) then
begin
DM.pFIBScript.Script.LoadFromFile (Filename) ;
DM.pFIBScript.ExecuteScript;
if not (SkriptError) then
begin
SetScriptRunStatus (sqlVersion.FieldByName('Major').AsInteger,
sqlVersion.FieldByName('Minor').AsInteger,
sqlVersion.FieldByName('Rel').AsInteger,
sqlVersion.FieldByName('Build').AsInteger,
// true,script.script.text) ;
true,DM.pFIBScript.script.text) ;
end ;
Refresh ;
sleep (800) ;
end else
begin
MessageDlg(format('Skriptdatei %s nicht gefunden.'+#13+#10+''+#13+#10+
'Update konnte nicht überspielt werden. Programm wird beendet.',[extractFilename(Filename)]), mtError, [mbOK], 0);
application.Terminate ;
end ;
end ;
frm_ScriptProgress.free ;
end ;
Das Problem ist dass eine Fehlermeldung erscheint:
Zitat:
Exception class EDatabaseError with message 'sqlVersion: Field 'Rel' not found'.
Sobald dieser Code aufgerufen wird:
RunDBScript (FieldByName('Major').AsInteger,
FieldByName('Minor').AsInteger,
FieldByName('Rel').AsInteger,
FieldByName('Build').AsInteger) ;
Was ich nicht verstehe ist dass sqlVersion das Feld Rel in der DB nicht findet, dieses ist aber vorhanden...
Auszug aus der DB
Code:
CREATE TABLE G_DB_VERSION (
ID D_INTEGER NOT NULL /* D_INTEGER = INTEGER */,
DB_DATE D_DATE NOT NULL /* D_DATE = DATE */,
MAJOR D_INTEGER NOT NULL /* D_INTEGER = INTEGER */,
MINOR D_INTEGER NOT NULL /* D_INTEGER = INTEGER */,
REL D_INTEGER NOT NULL /* D_INTEGER = INTEGER */,
BUILD D_INTEGER NOT NULL /* D_INTEGER = INTEGER */,
SCRIPT VARCHAR(32762) CHARACTER SET ASCII,
RUNNED D_SMALLINT /* D_SMALLINT = SMALLINT */
);
Bin dankbar für jeden Tipp.
Manfred
|