AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

DBF Spaltennamen ändern

Ein Thema von Kondzie · begonnen am 7. Aug 2019 · letzter Beitrag vom 8. Aug 2019
Antwort Antwort
Seite 1 von 2  1 2      
Kondzie

Registriert seit: 7. Aug 2019
5 Beiträge
 
#1

DBF Spaltennamen ändern

  Alt 7. Aug 2019, 15:41
Datenbank: DBF • Version: 3 • Zugriff über: UniDac
Hallo liebe Community!

Ich versuche gerade kopfzerbrechend einen Fehler bei mir zu finden und komme einfach nicht weiter...

Grundgedanke:
Ich möchte/muss einige Spaltennamen in DBASE III umbenennen. Da der ODBC-Treiber "dumm" ist, klappt ja kein "ALTER TABLE".
Deswegen speichere ich mir meine DBF-File in eine DBTable und führe dann mit einem Query ein "DROP", sowie ein "CREATE TABLE" mit den veränderten Spaltennamen aus.
Danach lade ich mir über den Query alle Daten aus meiner DBTabelle in die neu erstellte DBF-Tabelle.
Das möchte ich natürlich für mehrere Tabellen machen und führe deswegen ein Loop durch meinen "Datenbank-Ordner".
Diese Prozedure funktioniert einmnal und beim Laden der nächsten Tabelle in die DBTabelle tritt ein Fehler auf... ziemlich unlogischer, nebenbei bemerkt... :
"Es ist eine Exception der Klasse ESQLiteError mit der Meldung 'database table is locked' aufgetreten".

Ich verstehe weder, warum eine SQLite-Exception auftritt, noch warum die Tabelle locked ist, da ich sie ja noch nicht mal verwendet habe..

Hier meine Prozedur/Funktion:
Code:
function Tfrm_Main.Alter_DBF_Tables: Boolean;
const
  aTables:Array [0..6] of String = ('ALARM','CODBU','BACOFFST','HCLESE','HCRCAGRP','PERSCOD','SYSPARA');
var
  I,itablecnt,ibookingcnt: Integer;
  stable:string;
begin
  UniTableSource.active:=false;
  UniTableSource.Connection:=UniConDBF;
  UniQuery.Active:=false;
  UniQuery.Connection:=UniConDBF;
  ibookingcnt:=1;
  itablecnt:=0;

  while itablecnt< length(aTables) do
    begin

      stable:= aTables[itablecnt];

      if Check_BookingTable(sTable.ToUpper) then
        begin
          stable:= Format(stable+'%.*d',[2,ibookingcnt]);
          Inc(ibookingcnt);
        end;

      if not fileexists(UniConDBF.Database+sTable+'.dbf') then
        begin
          if not Check_BookingTable(sTable.ToUpper) then
              Inc(itablecnt)
          else if ibookingcnt>12 then
            Inc(itablecnt);

          continue;
        end;


      UniTableSource.active:=false;
      UniTableSource.TableName:=stable;
      UniTableSource.active:=true;

      UniQuery.SQL.Text:='DROP TABLE '+stable;
      UniQuery.ExecSQL;

      UniQuery.SQL.Clear;
      UniQuery.SQL.Add('CREATE TABLE '+stable+'(');
      for I := 0 to UniTableSource.Fieldcount-1 do
        begin
          if Check_Column(UniTableSource.Fields[i].FieldName.ToUpper) then
            UniQuery.SQL.Add('A'+UniTableSource.Fields[i].FieldName.ToUpper+' ')
          else
            UniQuery.SQL.Add(UniTableSource.Fields[i].FieldName.ToUpper+' ');

          UniQuery.SQL.Add(Lib.DataTypetoStrDBF(UniTableSource.Fields[i].DataType).ToUpper);
          if Lib.DataTypetoStrDBF(UniTableSource.Fields[i].DataType).ToUpper='CHAR' then
            if UniTableSource.Fields[i].DataSize>254 then
              UniQuery.SQL.Add(' (254)')
            else
              UniQuery.SQL.Add(' ('+UniTableSource.Fields[i].DataSize.ToString+')');
          if i<UniTableSource.Fieldcount-1 then
            UniQuery.SQL.Add(',')
          else
            UniQuery.SQL.Add(')');
        end;
      UniQuery.ExecSQL;

      UniQuery.SQL.Clear;

      while not UniTableSource.EOF do
        begin
          UniQuery.SQL.Clear;
          UniQuery.SQL.Add('INSERT INTO '+stable+' VALUES(');
          for I := 0 to UniTableSource.Fieldcount-1 do
            begin
              if Lib.DataTypetoStrDBF(UniTableSource.Fields[i].DataType).ToUpper='CHAR' then
                UniQuery.SQL.Add(QuotedStr(UniTableSource.Fields[i].AsString))
              else
                UniQuery.SQL.Add(UniTableSource.Fields[i].AsString);

              if i<UniTableSource.Fieldcount-1 then
                UniQuery.SQL.Add(',')
              else
                UniQuery.SQL.Add(');');
            end;
          UniQuery.ExecSQL;
          UniTableSource.Next;
        end;


      if not (Check_BookingTable(sTable.ToUpper)) then
        begin
          Inc(itablecnt);
          ibookingcnt:=1;
        end;

    end;

end;
Ich hoffe Ihr könnt mir irgendwie weiter helfen .. ich steh auf dem Schlauch

Grüße Kondzie!
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.275 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: DBF Spaltennamen ändern

  Alt 7. Aug 2019, 21:55
Hallo,
viel zu wenig Infos.

Welchen Datentyp haben deine verwendeten DB-Komponenten (UniXXX).
In welcher Zeile konkret kommt der Fehler bei der zweiten Tabelle.

Und es geht wirklich um DBase3 ???

PS:
Der "normale" weg wäre ja das Anlegen der neuen Spalte,
ein Rüberkopieren der Werte (Update) und löschen der alten Spalte.
Warum das Drop Table?
Heiko

Geändert von hoika ( 7. Aug 2019 um 22:00 Uhr)
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.275 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: DBF Spaltennamen ändern

  Alt 7. Aug 2019, 22:41
Hallo,
kurz gestöbert

Es gibt ja TDbf

https://sourceforge.net/projects/tdbf/

und dort

procedure RestructureTable(DbfFieldDefs: TDbfFieldDefs; Pack: Boolean);

Ich würde das mal damit probieren.
Heiko
  Mit Zitat antworten Zitat
Kondzie

Registriert seit: 7. Aug 2019
5 Beiträge
 
#4

AW: DBF Spaltennamen ändern

  Alt 8. Aug 2019, 07:54
Vielen Dank für deine bisherigen mühen Heiko!

Zitat:
Welchen Datentyp haben deine verwendeten DB-Komponenten (UniXXX).
Ich weiß nicht, was du in Klammern mit dem UniXXX meinst, aber eigentlich werden nur Numeric,Char und Date verwendet.

Zitat:
In welcher Zeile konkret kommt der Fehler bei der zweiten Tabelle.
Der Fehler tritt auf, wenn ich die nächste DBF-Tabelle in die DB-Tabelle lade.
Also hier:
Code:
UniTableSource.active:=false;
UniTableSource.TableName:=stable;
UniTableSource.active:=true;
Zitat:
Und es geht wirklich um DBase3 ???
Tatsächlich dachte ich das. Jetzt bin ich selber verwirrt. Also Die DBF-Dateien sind DBASE3, aber in meinem ConnectionString benutze ich das Format DBASE4 .... wenn ich es im ConnectionString umstelle, dann bekomme ich Datentyp-Fehler... aber darum geht es hier ja hoffentlich nicht ?

Zitat:
Der "normale" weg wäre ja das Anlegen der neuen Spalte,
ein Rüberkopieren der Werte (Update) und löschen der alten Spalte.
Warum das Drop Table?
Da ich ja den Tabellennamen beibehalten will, kann ich kein "CREATE" machen, da ja der Name zu diesem Zeitpunkt noch besteht. Deswegen erst "Drop", dann "CREATE".
Oder liege ich da jetzt komplett Falsch?

Zitat:
Es gibt ja TDbf
Ja das könnte ich auch mal ausprobieren. Danke dafür.
  Mit Zitat antworten Zitat
BerndS

Registriert seit: 8. Mär 2006
Ort: Jüterbog
491 Beiträge
 
Delphi 12 Athens
 
#5

AW: DBF Spaltennamen ändern

  Alt 8. Aug 2019, 08:19
Da sich bei TDBF seit 11/2015 nichts mehr tut, wäre für die neueren Delphi Versionen TVKDBF wahrscheinlich besser geeignet.

Nachtrag: RestructureTable gibt es in leider nicht. Müsste man dann selber umsetzen.

Geändert von BerndS ( 8. Aug 2019 um 08:26 Uhr)
  Mit Zitat antworten Zitat
exilant

Registriert seit: 28. Jul 2006
134 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: DBF Spaltennamen ändern

  Alt 8. Aug 2019, 09:33
Der Header von DBFs ist trivial. Kannst Du mit jedem Hex-Editor patchen.


DBF Header Structure
Anything, carried to the extreme, becomes insanity. (Exilant)
  Mit Zitat antworten Zitat
Kondzie

Registriert seit: 7. Aug 2019
5 Beiträge
 
#7

AW: DBF Spaltennamen ändern

  Alt 8. Aug 2019, 09:43
Zitat:
Der Fehler tritt auf, wenn ich die nächste DBF-Tabelle in die DB-Tabelle lade.
Also hier:
markieren
Code:
UniTableSource.active:=false;
UniTableSource.TableName:=stable;
UniTableSource.active:=true;
Das stimmt nicht! Der Fehler tritt auf, wenn ich Versuche die nächste Tabelle zu löschen, also hier:

Code:
UniQuery.SQL.Text:='DROP TABLE '+stable;
UniQuery.ExecSQL;

Der ganze Sinn hinter der Sache ist ja auch, dass ich von DBASE loskommen möchte. Da es aber in manchen Tabellen unüberlegte Spaltennamen gibt, wie "DATE/TIME/TYPE" etc., fällt das Konvertieren nach z.B. SQL Server schwer. Deswegen muss ich das erstmal ändern.


Anscheinend gebe ich irgendeine Instanz nicht ordentlich wieder frei. Aber dafür fehlen mir die nötigen Kenntnisse über Delphi, da ich ein "Neuling" bin.
Könnt Ihr was in meiner Funktion erkennen, was nicht ordentlich freigegeben ist oder dergleichen?

Geändert von Kondzie ( 8. Aug 2019 um 10:03 Uhr)
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.275 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: DBF Spaltennamen ändern

  Alt 8. Aug 2019, 10:03
Hallo,
Zitat:
fällt das Konvertieren nach z.B. SQL Server schwer
Nein, tut es nicht.

Ich hatte mir damals beim Umstieg von Paradox auf Interbase
ein eigenes Copy-Programm geschrieben.
Ich kannte ja die Tabellen mit den "bösen" Feldnamen
und habe die entsprechend berücksichtigt.


Zitat:
Nachtrag: RestructureTable gibt es in leider nicht. Müsste man dann selber umsetzen.
Eben deshalb die alte Version TDbf benutzen.
Heiko

Geändert von hoika ( 8. Aug 2019 um 10:06 Uhr)
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.275 Beiträge
 
Delphi 10.4 Sydney
 
#9

AW: DBF Spaltennamen ändern

  Alt 8. Aug 2019, 10:09
Hallo,
Zitat:
Anscheinend gebe ich irgendeine Instanz nicht ordentlich wieder frei.
es kann aber auch sein, dass Du das aktuelle Daten-Verzeichnis irgendwie abänderst,
dann findet das Programm die Tabelle wirklich nicht
GetCurrentDir
http://www.delphibasics.co.uk/RTL.as...=GetCurrentDir
Heiko
  Mit Zitat antworten Zitat
Kondzie

Registriert seit: 7. Aug 2019
5 Beiträge
 
#10

AW: DBF Spaltennamen ändern

  Alt 8. Aug 2019, 10:17
Zitat:
es kann aber auch sein, dass Du das aktuelle Daten-Verzeichnis irgendwie abänderst,
dann findet das Programm die Tabelle wirklich nicht
Naja ich Lösche und Erstelle neue Tabellen, vielleicht fällt das unter abändern?

Aber ich habe gerade alles versucht um die Instanzen zu schließen. Ich habe jetzt zwischendrin meine Connection gelöscht und neu verbunden, um ganz sicher zu gehen.
Leider funktioniert es auch so nicht.
Ich verstehe einfach nicht, warum die Tabelle, die ich ja noch gar nicht verwendet habe, gesperrt ist.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      

 

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: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