AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Aktualisieren der DB beim Kunden
Thema durchsuchen
Ansicht
Themen-Optionen

Aktualisieren der DB beim Kunden

Ein Thema von Hobbycoder · begonnen am 10. Feb 2025 · letzter Beitrag vom 11. Feb 2025
Antwort Antwort
Frickler

Registriert seit: 6. Mär 2007
Ort: Osnabrück
620 Beiträge
 
Delphi XE6 Enterprise
 
#1

AW: Aktualisieren der DB beim Kunden

  Alt 11. Feb 2025, 10:01
Jede Datenbank hat virtuelle Tabellen mit Metadaten, aus denen man entnehmen kann, wie die Datenbank aufgebaut ist, wie die Tabellen heißen, welche Felder sie haben, welche Typen die haben usw. Die musst Du einfach abfragen, so bekommst Du die benötigten Infos.
Siehe https://mariadb.com/kb/en/informatio...-tables-table/
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.340 Beiträge
 
Delphi 12 Athens
 
#2

AW: Aktualisieren der DB beim Kunden

  Alt 11. Feb 2025, 10:30
Ach ja, bezüglich der AppVersion und DBVersion,
denn es kann ja auch vorkommen, dass
* man mit unterschiedlichen ProgrammVersionen auf die selbe DB zugreift
* oder mit einem Programm auf unterschiedliche Datenbanken.

Für bestimmte Dinge, im Programm, benötigt es eine gewisse DB-Version,
aber für gewisse Funktionen/Strukturen/Daten, benötigt es eine gewisse Programm-Version.
(Minimal-Version und Maximal-Version)

Die Anwendung setzt also voraus, dass die DB eine bestimmte (die gleiche) Version besitzt, bzw. in einem vorgegebenen Versionsbereich vorliegt.
Und/oder andersrum, eine bestimmte DB-Version setzt eine Anwendung vor, welche in einem gewissenen Versionsbereich liegt.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (11. Feb 2025 um 10:32 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von TigerLilly
TigerLilly

Registriert seit: 24. Mai 2017
Ort: Wien, Österreich
1.241 Beiträge
 
Delphi 12 Athens
 
#3

AW: Aktualisieren der DB beim Kunden

  Alt 11. Feb 2025, 14:21
Nachtrag: Wenn man TMS Aurelius als ORM verwendet, dann zieht das ORM die DB automatisch mit.
Certified Delphi Developer (2025)
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
1.002 Beiträge
 
#4

AW: Aktualisieren der DB beim Kunden

  Alt 11. Feb 2025, 16:45
Danke für die zahlreichen Inspirationen/Informationen.

Jede Datenbank hat virtuelle Tabellen mit Metadaten, aus denen man entnehmen kann, wie die Datenbank aufgebaut ist, wie die Tabellen heißen, welche Felder sie haben, welche Typen die haben usw. Die musst Du einfach abfragen, so bekommst Du die benötigten Infos.
Siehe https://mariadb.com/kb/en/informatio...-tables-table/
Das ist (zumindest für mich) eine richtig gute Idee, weil mir das das Auswerten und verlgeichen der DB supereinfach macht. Mir geht's ja nur darum
- Neue Tabellen zur erzeugen
- Weggefallene Tabellen zu löschen
- Neue Columns hinzufügen
- Weggefallene Columns zu entfernen
- Datetype und Länge der Columns überprüfen und anpassen
- Defaultwert der Columns überprüfen und anpassen

Das konnte ich jetzt mit eine kleine Klasse erledigen, die ich hier mal reinsetze falls das mal irgendwer gebrauchen kann.

Delphi-Quellcode:
unit uTestTables2;

interface

uses System.Classes, System.SysUtils, ZConnection, ZDataset, Data.DB, System.Generics.Collections,
  uRWStream;

type
  TModifyFlag=(mfNoChanges, mfAdd, mfModify, mfDelete);
  TColumnModifyFlag=(cmfNone, cmfDatatype, cmfDefaultValue);

  TDBColumn=class
  private
    FName: string;
    FColumnDefault: string;
    FColumnType: string;
    FModifyFlag: TModifyFlag;
    FColumnModifyFlag: TColumnModifyFlag;
    procedure SetColumnDefault(const Value: string);
    procedure SetColumnType(const Value: string);
    procedure SetName(const Value: string);
    procedure SetModifyFlag(const Value: TModifyFlag);
    procedure SetColumnModifyFlag(const Value: TColumnModifyFlag);
  public
    constructor Create;
    procedure WriteToStream(st: TStream);
    procedure ReadFromStream(st: TStream; Version: Integer);
    procedure Compare(Source: TObject);
    procedure Assign(Source: TObject);
    function GetDefault: string;
  published
    property Name: string read FName write SetName;
    property ColumnType: string read FColumnType write SetColumnType;
    property ColumnDefault: string read FColumnDefault write SetColumnDefault;
    property ModifyFlag: TModifyFlag read FModifyFlag write SetModifyFlag;
    property ColumnModifyFlag: TColumnModifyFlag read FColumnModifyFlag write SetColumnModifyFlag;
  end;

  TDBTable=class(TObjectList<TDBColumn>)
  private
    FName: string;
    FCollation: string;
    FModifyFlag: TModifyFlag;
    procedure SetCollation(const Value: string);
    procedure SetName(const Value: string);
    procedure SetModifyFlag(const Value: TModifyFlag);
  public
    procedure WriteToStream(st: TStream);
    procedure ReadFromStream(st: TStream; Version: Integer);
    procedure Compare(Source: TObject);
    function GetColumnByName(value: string): TDBColumn;
    procedure Assign(Source: TObject);
  published
    property Name: string read FName write SetName;
    property Collation: string read FCollation write SetCollation;
    property ModifyFlag: TModifyFlag read FModifyFlag write SetModifyFlag;
  end;

  TDBDatabase=class(TObjectList<TDBTable>)
  private
    FFilename: string;
    FSchemaName: string;
    FCollation: string;
    procedure SetCollation(const Value: string);
    procedure SetSchemaName(const Value: string);
    function GetSchema(Con: TZConnection; Schema: string): Boolean;
    procedure GetTables(Con: TZConnection; Schema: string);
    procedure GetColumns(Con: TZConnection; Schema: string; TT: TDBTable);
  public
    procedure Compare(Source: TObject);
    procedure BuildFromDB(Con: TZConnection; RootPass: string; Schema: string);
    procedure LoadFromFile(Filename: string = '');
    procedure SaveToFile(Filename: string = '');
    function GetTableByName(value: string): TDBTable;
    function IsModified: Boolean;
    function CreateTableScript(Script: TStrings): Boolean;
    function ExecSQLLine(Con: TZConnection; Line: string): Boolean;
  published
    property SchemaName: string read FSchemaName write SetSchemaName;
    property Collation: string read FCollation write SetCollation;
  end;

Const
  FileVersion = 1;
  StringSeparator = '`';

implementation

{ TDBColumn }

procedure TDBColumn.Assign(Source: TObject);
var
  TC: TDBColumn;
begin
  if Source is TDBColumn then
  begin
    TC:=TDBColumn(Source);
    self.FName:=TC.Name;
    self.FColumnType:=TC.ColumnType;
    self.FColumnDefault:=TC.ColumnDefault;
  end;
end;

procedure TDBColumn.Compare(Source: TObject);
var
  TC: TDBColumn;
begin
  Self.FModifyFlag:=mfNoChanges;
  if Source is TDBColumn then
  begin
    TC:=TDBColumn(Source);
    if (self.FColumnDefault<>TC.ColumnDefault) then
    begin
      Self.FModifyFlag:=mfModify;
      self.FColumnModifyFlag:=cmfDefaultValue;
      self.FColumnDefault:=TC.ColumnDefault;
    end;
    if (self.FColumnType<>TC.ColumnType) then
    begin
      Self.FModifyFlag:=mfModify;
      self.FColumnModifyFlag:=cmfDatatype;
      self.FColumnType:=TC.ColumnType;
    end;
  end;
end;

constructor TDBColumn.Create;
begin
  inherited;
  Self.FColumnModifyFlag:=cmfNone;
end;

function TDBColumn.GetDefault: string;
begin
  if self.FColumnDefault<>'NULLthen
    Result:=''''+self.FColumnDefault+'''else
    Result:=Self.FColumnDefault;
end;

procedure TDBColumn.ReadFromStream(st: TStream; Version: Integer);
begin
  if st<>nil then
  begin
    self.FName:=ReadStrFromStream(st);
    self.FColumnType:=ReadStrFromStream(st);
    self.FColumnDefault:=ReadStrFromStream(st);
  end;
end;

procedure TDBColumn.SetColumnDefault(const Value: string);
begin
  FColumnDefault := Value;
end;

procedure TDBColumn.SetColumnModifyFlag(const Value: TColumnModifyFlag);
begin
  FColumnModifyFlag := Value;
end;

procedure TDBColumn.SetColumnType(const Value: string);
begin
  FColumnType := Value;
end;

procedure TDBColumn.SetModifyFlag(const Value: TModifyFlag);
begin
  FModifyFlag := Value;
end;

procedure TDBColumn.SetName(const Value: string);
begin
  FName := Value;
end;

procedure TDBColumn.WriteToStream(st: TStream);
begin
  if st<>nil then
  begin
    WriteStrToStream(st, self.FName);
    WriteStrToStream(st, self.FColumnType);
    WriteStrToStream(st, self.FColumnDefault);
  end;
end;

{ TDBTable }

procedure TDBTable.Assign(Source: TObject);
var
  TT: TDBTable;
  TC: TDBColumn;
  I: Integer;
begin
  if Source is TDBTable then
  begin
    TT:=TDBTable(Source);
    self.FName:=TT.Name;
    self.FCollation:=TT.Collation;
    self.Clear;
    for I := 0 to TT.Count-1 do
    begin
      TC:=TDBColumn.Create;
      TC.Assign(TT[i]);
      TC.ModifyFlag:=mfAdd;
      self.Add(TC);
    end;
  end;
end;

procedure TDBTable.Compare(Source: TObject);
var
  TT: TDBTable;
  TC, TC2: TDBColumn;
  I: Integer;
begin
  if Source is TDBTable then
  begin
    TT:=TDBTable(Source);
    for I := 0 to Self.Count-1 do
    begin
      TC:=TT.GetColumnByName(self[i].Name);
      if TC<>nil then
        self[i].Compare(TC) else
        self[i].ModifyFlag:=mfDelete;
      if self[i].ModifyFlag<>mfNoChanges then self.FModifyFlag:=mfModify;
    end;
    for I := 0 to TT.Count-1 do
    begin
      TC:=self.GetColumnByName(TT[i].Name);
      if TC=nil then
      begin
        TC2:=TDBColumn.Create;
        TC2.Assign(TC);
        TC2.ModifyFlag:=mfAdd;
        self.Add(TC2);
        self.ModifyFlag:=mfModify;
      end;
    end;
  end;
end;

function TDBTable.GetColumnByName(value: string): TDBColumn;
var
  I: Integer;
begin
  Result:=nil;
  for I := 0 to Self.Count-1 do
    if self[i].Name.ToLower=value.ToLower then
    begin
      Result:=self[i];
      Break;
    end;
end;

procedure TDBTable.ReadFromStream(st: TStream; Version: Integer);
var
  TC: TDBColumn;
  I, C: Integer;
begin
  if st<>nil then
  begin
    Self.Clear;
    self.FName:=ReadStrFromStream(st);
    self.FCollation:=ReadStrFromStream(st);
    C:=ReadIntFromStream(st);
    for I := 0 to C-1 do
    begin
      TC:=TDBColumn.Create;
      TC.ReadFromStream(st, Version);
      self.Add(TC);
    end;
  end;
end;

procedure TDBTable.SetCollation(const Value: string);
begin
  FCollation := Value;
end;

procedure TDBTable.SetModifyFlag(const Value: TModifyFlag);
begin
  FModifyFlag := Value;
end;

procedure TDBTable.SetName(const Value: string);
begin
  FName := Value;
end;

procedure TDBTable.WriteToStream(st: TStream);
var
  I: Integer;
begin
  if st<>nil then
  begin
    WriteStrToStream(st, self.FName);
    WriteStrToStream(st, self.FCollation);
    WriteIntToStream(st, self.Count);
    for I := 0 to self.Count-1 do
      self[i].WriteToStream(st);
  end;
end;

{ TDBDatabase }

procedure TDBDatabase.BuildFromDB(Con: TZConnection; RootPass: string; Schema: string);
var
  FCon: TZConnection;
  FQ: TZQuery;
begin
  FCon:=TZConnection.Create(nil);
  try
    FCon.HostName:=Con.HostName;
    FCon.Port:=Con.Port;
    FCon.User:='root';
    Fcon.Password:=RootPass;
    Fcon.Database:='information_schema';
    Fcon.Protocol:=Con.Protocol;
    Fcon.LibraryLocation:=Con.LibraryLocation;
    Fcon.LibLocation:=Con.LibLocation;
    try
      FCon.Connect;
      if FCon.Connected then
      begin
        self.Clear;
        self.FSchemaName:='';
        self.FCollation:='';
        if self.GetSchema(FCon, Schema) then
        begin
          Self.GetTables(FCon, Schema);
        end;
      end;
    except

    end;
  finally
    FCon.Free;
  end;
end;

procedure TDBDatabase.Compare(Source: TObject);
var
  DB: TDBDatabase;
  TT, TT2: TDBTable;
  I: Integer;
begin
  if Source is TDBDatabase then
  begin
    DB:=TDBDatabase(Source);
    for I := 0 to self.Count-1 do
    begin
      TT:=DB.GetTableByName(self[i].Name);
      if TT<>nil then
        self[i].Compare(TT) else
        self[i].ModifyFlag:=mfDelete;
    end;
    for i:=0 to db.Count-1 do
    begin
      TT:=self.GetTableByName(DB[i].Name);
      if TT=nil then
      begin
        TT2:=TDBTable.Create(True);
        TT2.Assign(DB[i]);
        TT2.ModifyFlag:=mfAdd;
        self.Add(TT2);
      end;
    end;
  end;
end;

function TDBDatabase.CreateTableScript(Script: TStrings): Boolean;
var
  s: string;
  I: Integer;
  C: Integer;
begin
  Script.Clear;
  Result:=False;
  try
    Script.Add('USE '+StringSeparator+self.SchemaName+StringSeparator+';');
    for I := 0 to self.Count-1 do
    begin
      case self[i].ModifyFlag of
        mfAdd:
        begin
          s:='CREATE TABLE '+StringSeparator+self[i].Name+StringSeparator+' (';
          for C := 0 to self[i].Count-1 do
          begin
            s:=s+StringSeparator+self[i][C].Name+StringSeparator+' '+self[i][c].ColumnType+' DEFAULT '+self[i][c].ColumnDefault+' ,';
          end;
          s:=Copy(s, 1, Length(s)-2);
          s:=s+') COLLATE='''+self[i].Collation+''';';
          Script.Add(S);
        end;
        mfModify:
        begin
          for C := 0 to self[i].Count-1 do
            case self[i][c].ModifyFlag of
              mfModify:
              begin
                s:='ALTER TABLE '+StringSeparator+self[i].Name+StringSeparator+' CHANGE COLUMN '+StringSeparator+self[i][C].Name+StringSeparator+' '+StringSeparator+self[i][C].Name+StringSeparator+' '+self[i][c].ColumnType+' DEFAULT '+self[i][c].GetDefault+';';
                Script.Add(s);
              end;
              mfAdd:
              begin
                s:='ALTER TABLE '+StringSeparator+self[i].Name+StringSeparator+' ADD COLUMN '+StringSeparator+self[i][C].Name+StringSeparator+' '+self[i][c].ColumnType+' DEFAULT '+self[i][c].GetDefault+';';
                Script.Add(s);
              end;
              mfDelete:
              begin
                s:='ALTER TABLE '+StringSeparator+self[i].Name+StringSeparator+' DROP COLUMN '+StringSeparator+self[i][C].Name+StringSeparator+';';
                Script.Add(s);
              end;
            end;
        end;
        mfDelete:
        begin
          s:='DROP TABLE '+StringSeparator+self[i].Name+StringSeparator+';';
          Script.Add(s);
        end;
      end;
    end;
    Result:=True;
  finally

  end;
end;

function TDBDatabase.ExecSQLLine(Con: TZConnection; Line: string): Boolean;
var
  q: TZQuery;
begin
  Result:=False;
  q:=TZQuery.Create(nil);
  try
    q.Connection:=Con;
    q.SQL.Text:=Line;
    q.ExecSQL;
    Result:=True;
  finally
    q.Free;
  end;
end;

procedure TDBDatabase.GetColumns(Con: TZConnection; Schema: string; TT: TDBTable);
var
  q: TZQuery;
  TC: TDBColumn;
begin
  q:=TZQuery.Create(nil);
  try
    q.Connection:=Con;
    q.SQL.Text:='Select * from COLUMNS where TABLE_SCHEMA=:schema and TABLE_NAME=:tablename order by ORDINAL_POSITION';
    q.Params.ParamValues['schema']:=Schema;
    q.Params.ParamValues['tablename']:=TT.Name;
    q.Active:=True;
    while not q.Eof do
    begin
      TC:=TDBColumn.Create;
      TT.Add(TC);
      TC.Name:=q.FieldByName('COLUMN_NAME').AsString;
      TC.ColumnType:=q.FieldByName('COLUMN_TYPE').AsString;
      TC.FColumnDefault:=q.FieldByName('COLUMN_DEFAULT').AsString;
      q.Next;
    end;
    q.Active:=False;
  finally
    q.Free;
  end;
end;

function TDBDatabase.GetSchema(Con: TZConnection; Schema: string): Boolean;
var
  q: TZQuery;
begin
  Result:=False;
  q:=TZQuery.Create(nil);
  try
    q.Connection:=Con;
    q.SQL.Text:='Select * from SCHEMATA where SCHEMA_NAME=:schema';
    q.Params.ParamValues['schema']:=Schema;
    q.Active:=True;
    if q.RecordCount>0 then
    begin
      self.FSchemaName:=q.FieldByName('SCHEMA_NAME').AsString;
      self.FCollation:=q.FieldByName('DEFAULT_COLLATION_NAME').AsString;
      Result:=True;
    end;
    q.Active:=False;
  finally
    q.Free;
  end;
end;

function TDBDatabase.GetTableByName(value: string): TDBTable;
var
  I: Integer;
begin
  Result:=nil;
  for I := 0 to Self.Count-1 do
    if self[i].Name.ToLower=value.ToLower then
    begin
      Result:=self[i];
      Break;
    end;
end;

procedure TDBDatabase.GetTables(Con: TZConnection; Schema: string);
var
  q: TZQuery;
  TT: TDBTable;
  TC: TDBColumn;
begin
  q:=TZQuery.Create(nil);
  try
    q.Connection:=Con;
    q.SQL.Text:='Select * from TABLES where TABLE_SCHEMA=:schema order by TABLE_NAME';
    q.Params.ParamValues['schema']:=Schema;
    q.Active:=True;
    while not q.Eof do
    begin
      TT:=TDBTable.Create(True);
      self.Add(TT);
      TT.Name:=q.FieldByName('TABLE_NAME').AsString;
      TT.Collation:=q.FieldByName('TABLE_COLLATION').AsString;
      GetColumns(Con, Schema, TT);
      q.Next;
    end;
    q.Active:=False;
  finally
    q.Free;
  end;
end;

function TDBDatabase.IsModified: Boolean;
var
  I: Integer;
begin
  Result:=False;
  for I := 0 to self.Count-1 do
    if self[i].ModifyFlag<>mfNoChanges then
    begin
      Result:=True;
      Break;
    end;
end;

procedure TDBDatabase.LoadFromFile(Filename: string);
var
  st: TFileStream;
  Version: Integer;
  I, C: Integer;
  TT: TDBTable;
begin
  if Filename<>'then FFilename:=Filename;
  if FileExists(FFilename) then
  begin
    Self.Clear;
    self.FSchemaName:='';
    self.FCollation:='';
    st:=TFileStream.Create(FFilename, fmOpenRead);
    if st<>nil then
    try
      Version:=ReadIntFromStream(st);
      self.FSchemaName:=ReadStrFromStream(st);
      self.FCollation:=ReadStrFromStream(st);
      C:=ReadIntFromStream(st);
      for I := 0 to C-1 do
      begin
        TT:=TDBTable.Create(True);
        TT.ReadFromStream(st, Version);
        self.Add(TT);
      end;
    finally
      st.Free;
    end;
  end;
end;

procedure TDBDatabase.SaveToFile(Filename: string);
var
  st: TFileStream;
  I: Integer;
begin
  if Filename<>'then FFilename:=Filename;
  if DirectoryExists(ExtractFilePath(FFilename)) then
  begin
    st:=TFileStream.Create(FFilename, fmCreate);
    if st<>nil then
    try
      WriteIntToStream(st, FileVersion);
      WriteStrToStream(st, self.FSchemaName);
      WriteStrToStream(st, self.FCollation);
      WriteIntToStream(st, self.Count);
      for I := 0 to self.Count-1 do
        self[i].WriteToStream(st);
    finally
      st.Free;
    end;
  end;
end;

procedure TDBDatabase.SetCollation(const Value: string);
begin
  FCollation := Value;
end;

procedure TDBDatabase.SetSchemaName(const Value: string);
begin
  FSchemaName := Value;
end;

end.
Aufruf:

Delphi-Quellcode:
var
  DB, DB2: TDBDatabase;
  sl: TStringList;
  I: Integer;
  q: TZQuery;
begin
  DB:=TDBDatabase.Create(True);
  DB2:=TDBDatabase.Create(True);
  sl:=TStringList.Create;
  try
    if ExtactDBResource then
    begin
      DB.BuildFromDB(con1, '123456', 'testschema'); //Hier muss das Root-Passwort der DB verwendet werden.
      DB2.LoadFromFile(ExtractFilePath(Application.ExeName)+'testschema.shdat');
      DB.Compare(DB2);
      if DB.IsModified then
      begin
        if DB.CreateTableScript(sl) then
        begin
          if sl.Count>1 then
          begin
            for I := 1 to sl.Count-1 do
            begin
              DB.ExecSQLLine(con1, sl[i]);
            end;
          end;
        end;
      end;
    end;
  finally
    DB.Free;
    DB2.Free;
    sl.Free;
  end;
Die Proceduren LoadFromFile, SaveToFile, ReadFromStream und WriteToStream muss man zum Testen rausschmeißen.
Wer die dafür notwendige Unit haben möchte, kann mich ja anschreiben.
Und wer nicht ZEOS verwendet, muss das für seine vewendete DB-Komponenten anpassen.

Das ganze ist natürlich recht einfach gehalten, weil es mir ja nur um die o.g. Tabellen- und Feldeigenschaften geht. Wer mehr will, kann das ja entsprechend anpassen.
Angehängte Dateien
Dateityp: pas uTestTables2.pas (15,4 KB, 3x aufgerufen)
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.
  Mit Zitat antworten Zitat
Benutzerbild von TigerLilly
TigerLilly

Registriert seit: 24. Mai 2017
Ort: Wien, Österreich
1.241 Beiträge
 
Delphi 12 Athens
 
#5

AW: Aktualisieren der DB beim Kunden

  Alt 11. Feb 2025, 17:28
Wow. Das ist ja eine Kanone für Spatzen. Ich weiß nicht. Änderungen an der Db ziehen oft Änderungen an den Daten nach sich. Manchmal werden Felder umbenannt + der Inhalt darf aber nicht verloren gehen. Ebenso wenn sich der Typ eienes Feldes ändert. Manche Änderungen können nur gemcht werden, wenn Constraints/Indeces/Trigger uä deaktiviert und danach aktiviert werden. Das zu Automatisieren scheint mir schwierig zu sein.

Wie gesagt, ich bin mit sowas völlig zufrieden, weil ich ja selber weiß, was sich ändern muss.

Code:
 Result := Result and DoVersion(nVersion, 16, 'ALTER TABLE TBLMATERIAL DROP COLUMN BIO; ALTER TABLE TBLMATERIAL ADD BIO T_CHAR NULL',
      'Spalte Bio in der Tabelle Material erstellen ...');
    Result := Result and DoVersion(nVersion, 17, 'ALTER TABLE TBLMATERIAL ALTER COLUMN QUIDTEXT T_LONGTEXT',
      'Die Grösse der Spalte Quidtext in der Tabelle Material wird erhöht ...');
    Result := Result and DoVersion(nVersion, 18, 'ALTER TABLE TBLMATERIAL ADD LOSGROESSE T_INTEGER DEFAULT 1',
      'Bei den Materialien kann eine Losgröße hinterlegt werden ...');
    Result := Result and DoVersion(nVersion, 19, 'UPDATE TBLMATERIAL SET LOSGROESSE= 1', 'Losgröße auf 1 setzen ...');
    Result := Result and DoVersion(nVersion, 20, 'ALTER TABLE TBLMATERIAL ADD BIOZUTATEN T_TEXT;', 'Feld für Biozutaten ergänzen ...');
    Result := Result and DoVersion(nVersion, 21, 'ALTER TABLE TBLSPEISEPLAN ADD MENU T_CODE;', 'Feld für Menü ergänzen ...');
    Result := Result and DoVersion(nVersion, 22, 'ALTER TABLE TBLMATERIAL ADD ZL_TAGS T_TEXT;' + 'ALTER TABLE TBLZUTAT ADD ZL_PRO_BT T_BOOLEAN;',
      'Materialstamm TAGS ergänzen ...');
    s     := GetSQLResult('SELECT name FROM sysobjects with (nolock) WHERE (name LIKE ''%LOS%'')');
    if (Trim(s) <> '') then begin
      Result := Result and DoVersion(nVersion, 23, 'ALTER TABLE TBLMATERIAL DROP CONSTRAINT ' + s,
        'Andert die Spalte Lossgröße in der Materialien ...');
      Result := Result and DoVersion(nVersion, 23, 'ALTER TABLE TBLMATERIAL ALTER COLUMN LOSGROESSE T_FLOAT',
        'Andert die Spalte Lossgröße in der Materialien ...');
    end;
Certified Delphi Developer (2025)
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
1.002 Beiträge
 
#6

AW: Aktualisieren der DB beim Kunden

  Alt 11. Feb 2025, 18:15
Wow. Das ist ja eine Kanone für Spatzen. Ich weiß nicht. Änderungen an der Db ziehen oft Änderungen an den Daten nach sich. Manchmal werden Felder umbenannt + der Inhalt darf aber nicht verloren gehen. Ebenso wenn sich der Typ eienes Feldes ändert. Manche Änderungen können nur gemcht werden, wenn Constraints/Indeces/Trigger uä deaktiviert und danach aktiviert werden. Das zu Automatisieren scheint mir schwierig zu sein.
Ist ja nur für mich. Ich nutze das auch gleich zum Anlegen beim Kunden, und hab das noch um das Anlegen und Prüfen von DB/User/Rights erweitert. Klar geht das auch anders, aber so konnte ich das jetzt für mich fertig stellen.
Eine Erweiterung um Indices etc. könnte man da ja noch nach dem gleichen Prizip machen. Meine Anforderungen an die Datenbank sind beim mir (und dem Projekt) sicherlich um einiges kleiner, als bei deinen Projekten.
In meinen Tabellen ändern sich in der Regel keine Column- oder Tabellen-Namen.

Mir geht es mehr darum, dass durch Erweiterung des Projekt Felder und Tabellen hinzukommen und das sicher und ohne großen Aufwand vom Benutzer umgesetzt werden kann.
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.

Geändert von Hobbycoder (11. Feb 2025 um 19:24 Uhr)
  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 19:48 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