AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Datenbank ( Tabellen ) Aktualisierung
Thema durchsuchen
Ansicht
Themen-Optionen

Datenbank ( Tabellen ) Aktualisierung

Ein Thema von manfred_h · begonnen am 12. Aug 2010 · letzter Beitrag vom 13. Aug 2010
Antwort Antwort
manfred_h

Registriert seit: 4. Nov 2005
Ort: Basel
442 Beiträge
 
Delphi XE2 Enterprise
 
#1

Datenbank ( Tabellen ) Aktualisierung

  Alt 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
  Mit Zitat antworten Zitat
Mschmidt

Registriert seit: 4. Jul 2010
Ort: Berlin
62 Beiträge
 
Delphi XE2 Professional
 
#2

AW: Datenbank ( Tabellen ) Aktualisierung

  Alt 12. Aug 2010, 19:46
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
  Mit Zitat antworten Zitat
manfred_h

Registriert seit: 4. Nov 2005
Ort: Basel
442 Beiträge
 
Delphi XE2 Enterprise
 
#3

AW: Datenbank ( Tabellen ) Aktualisierung

  Alt 12. Aug 2010, 20:12
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
  Mit Zitat antworten Zitat
Lemmy

Registriert seit: 8. Jun 2002
Ort: Berglen
2.381 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Datenbank ( Tabellen ) Aktualisierung

  Alt 13. Aug 2010, 13:41
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
  Mit Zitat antworten Zitat
Benutzerbild von fkerber
fkerber
(CodeLib-Manager)

Registriert seit: 9. Jul 2003
Ort: Ensdorf
6.723 Beiträge
 
Delphi XE Professional
 
#5

AW: Datenbank ( Tabellen ) Aktualisierung

  Alt 13. Aug 2010, 13:47
Hi,


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
Frederic Kerber
  Mit Zitat antworten Zitat
manfred_h

Registriert seit: 4. Nov 2005
Ort: Basel
442 Beiträge
 
Delphi XE2 Enterprise
 
#6

AW: Datenbank ( Tabellen ) Aktualisierung

  Alt 13. Aug 2010, 14:02
Besten Dank für den Hinweis. Leider erhalte ich da nur die Fehlermeldung:
Zitat:
ERROR: unable to connect to source database!
  Mit Zitat antworten Zitat
manfred_h

Registriert seit: 4. Nov 2005
Ort: Basel
442 Beiträge
 
Delphi XE2 Enterprise
 
#7

AW: Datenbank ( Tabellen ) Aktualisierung

  Alt 13. Aug 2010, 15:24
Hallo zusammen

hab's doch noch gefunden.
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 MakeBackup; aufgerufen wurde welches die DB nicht mehr öffnete...

Danke trozdem für die Tipp's.
Shalom
Manfred
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:34 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