Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Datenbank ( Tabellen ) Aktualisierung (https://www.delphipraxis.net/153686-datenbank-tabellen-aktualisierung.html)

manfred_h 12. Aug 2010 17:13

Datenbank: Firebird • Version: 2.1 • Zugriff über: Fibplus

Datenbank ( Tabellen ) Aktualisierung
 
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

Mschmidt 12. Aug 2010 18:46

AW: Datenbank ( Tabellen ) Aktualisierung
 
Hi,
ohne jetzt den Code en detail zu lesen und zu verstehen, was genau ist dein Problem bzw. was möchtest du erreichen?
Ich habe den Verdacht, dass hier mit Kanonen auf Spatzen geschossen wird, wenns um ne simple Versionsabfrage geht und
deren Änderung.
:-mschmidt

manfred_h 12. Aug 2010 19:12

AW: Datenbank ( Tabellen ) Aktualisierung
 
Zitat:

Zitat von Mschmidt (Beitrag 1041676)
Hi,was möchtest du erreichen?

Die Idee ist dass wenn Änderungen an der DB zu erledigen sind,
kann einfach eine Datei mit den Änderungen z.B.
Code:
ALTER TABLE MBP
ADD "1_LIST_MAIN_OK" I_O /* I_O = VARCHAR(10) */;
durch das Setup verteilt werden. Das importieren wird dann alles automatisch durchgeführt. Zuerst wird geprüft ob die DB Version gleich oder älter ist als die Programmversion und dann die allfälligen Anpassungen vorgenommen.

Manfred

Lemmy 13. Aug 2010 12:41

AW: Datenbank ( Tabellen ) Aktualisierung
 
hi,

habe ich schon mal gesagt, dass ich With XXX do hasse?

Wenn der Fehler wirklich an der von dir angezeigten Stelle auftritt, dann hat das IMHo nichts mit der Datenbank zu tun, die Query ist an der Stelle ja offen, d.h. wenn in der Tabelle was fehlen würde, dann würde die Exception beim Open auftreten.

Soll heißen: es gibt halt in der Query nun mal kein Feld mit Namen "Rel". Hast Du das mal mit dem Debugger geprüft welche Felder in der QUery da sind?

GRüße

fkerber 13. Aug 2010 12:47

AW: Datenbank ( Tabellen ) Aktualisierung
 
Hi,

Zitat:

Zitat von manfred_h (Beitrag 1041657)

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.. )


Vielleicht hilft dir das hier weiter:
http://www.delphipraxis.net/151932-t...portieren.html


Liebe Grüße,
Frederic

manfred_h 13. Aug 2010 13:02

AW: Datenbank ( Tabellen ) Aktualisierung
 
Zitat:

Zitat von fkerber (Beitrag 1041868)
Hi,
Vielleicht hilft dir das hier weiter:
http://www.delphipraxis.net/151932-t...portieren.html

Besten Dank für den Hinweis. Leider erhalte ich da nur die Fehlermeldung:
Zitat:

ERROR: unable to connect to source database!
:oops:

manfred_h 13. Aug 2010 14:24

AW: Datenbank ( Tabellen ) Aktualisierung
 
Hallo zusammen

hab's doch noch gefunden. :cyclops:
Das Problem war dass vor dem Aufruf von
Delphi-Quellcode:
      RunDBScript (FieldByName('Major').AsInteger,
                  FieldByName('Minor').AsInteger,
                  FieldByName('Rel').AsInteger,
                  FieldByName('Build').AsInteger) ;
      next ;
noch ein
Delphi-Quellcode:
MakeBackup;
aufgerufen wurde welches die DB nicht mehr öffnete... :pale:

Danke trozdem für die Tipp's.
Shalom
Manfred


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:26 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz