Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Automatische Felder in der Access-DB erzeugen (https://www.delphipraxis.net/805-automatische-felder-der-access-db-erzeugen.html)

m-werk 9. Sep 2002 14:14


Automatische Felder in der Access-DB erzeugen
 
Hallo Leute, wie kann ich, wenn ich eine Access-DB habe, und ich aber einige Felder vergessen habe, die aus meinem Programm automatisch hinzufügen?

Es soll so sein, dass wenn ein User das Update meines Programmes installiert und dann im Menüpunkt auf 'Aktualisieren' klickt, dass dann automatisch einige Felder in einer Tabelle in der Datenbank erstellt werden, damit dann das Programm auch richtig läuft und der User auch zugriff auf die Felder hat?

Grund ist der, da ja einige User schon das Programm haben und ich jetzt ein Update machen möchte. Dafür fehlen jetzt aber einige Felder in der Access-DB.

Kann man das überhaupt? Und wenn ja, Wie?

Klabautermann 9. Sep 2002 14:38

Hallo,

ich habe es mit Access noch nicht Probiert, aber generell sollte das kein Problem sein.

Du musst auf jeden Fall den Exclusiven Zugriff auf die Tabelle haben (es darf also keine zweite Connection bestehen).
Danach fährst du ein Querry das so aufgebaut ist:
Code:
ALTER TABLE tabellenname ADD
 (
  Alter NUMERIC
  Nummernschild CHAR(20)
 )
Wenn du pech hast können die Felder bei Acces nur einzeln hinzugefügt werden. In dem Fall musst du es in zwei Querys aufteilen:
Code:
ALTER TABLE tabellenname ADD Alter NUMERIC
ALTER TABLE tabellenname ADD Nummernschild CHAR(20)
Gruß
Klabautermann

m-werk 12. Sep 2002 14:18

Hi, und wie kann ich das mit einem Button verbinden?

Ich möchte auf den Button klicken, und dann sollen die Felder in der Datenbank erzeugt werden. Und weiters soll man, sobald diese erzeugt sind, darauf zugreifen können.

MrSpock 12. Sep 2002 15:28

Hallo m-werk,

das Statement der SQL Eigenschaft einer TQuery Komponente hinzufügen. Die TQuery Komponente mit der Datenbank verbinden. Dann dem OnClick - Ereignis des Schalters den Code:

Code:
qryAdd.ExecSQL;
hinzufügen, wobei du den Namen qryAdd durch den Namen der o.g. TQuery Kompo ersetzen muss.

m-werk 13. Sep 2002 18:30

Hi, ich habe jetzt alles so gemacht, aber nun kommt, wenn ich den Button betätige eine Meldung: Syndaxfehler in Felddefinition.

Ich habe schon vorgefertigte Tabellen in der Access. Ich möchte in der Tabelle 'Kinder' eineFeld 'Zusatz' hinzufügen, der ein Text sein soll.
Weiters möchte ich noch ein Feld 'XY' hinzufügen, der eine Zahl sein soll.

Ich komm nicht dahinter, wie die SQL eigenschaft heißen soll.

MrSpock 13. Sep 2002 20:42

Hallo m-werk,

wann kommt denn der Syntax Fehler?

Der SQL String sollte lauten:

Code:
ALTER TABLE Kinder ADD Zusatz CHAR(20)
und ggf. eine zweite Anweisung:
Code:
ALTER TABLE Kinder ADD XY NUMERIC
Die entsprechende TQuery Kompo muss natürlich mit der Datenbank verbunden sein und kein anderer sollte zu dem Zeitpunkt auf die Daten zugreifen.

m-werk 14. Sep 2002 17:40

So, ich habe es jetzt geschaft.
Ich habe aber bemerkt, dass ich immer nur einen String verwenden kann.
Ich muß aber 9 Felder hinzufügen.

Muß ich jetzt 9 Querys machen? Oder kann ich das irgendwie in einer einzigen auch machen?

Weiters muß ich ein Feld hinzufügen, dass wie folgt aussehen muß:
Feldname: Rundung
Felddatentyp: Zahl
Feldgröße: Double
Format: Standartzahl oder Euro
Dezimalstellenanzeige: 3

Wie bekomme ich das hin?

MrSpock 16. Sep 2002 20:55

Hallo m-werk,

das Feld kannst du mit:

Code:
ALTER TABLE Kinder ADD Rundung NUMERIC
Dabei ist es auch denkbar FLOAT oder MONEY zu nutzen. Letzteres hat aber nur 2 Nachkommastellen.

Du kannst übrigens alles nacheinander in dieselbe TQuery Komponente schreiben. Die SQL Eigenschaft einfach mit Clear löschen, neu setzen und mit ExecSQL ausführen.

Formate kannst du in Delphi über die Field Komponente einstellen, die du über den Feldeditor hinzufügen kannst. Das Format über SQL so einzustellen, dass es beim Öffnen der DB in Access wie von dir gewünscht angezeigt wird, geht nicht.

m-werk 17. Sep 2002 07:11

Hi, also geht das einstellen vom Format wie z.B. 'Standartzahl oder Euro' nicht.

Was bedeutet FLOAT und MONEY?
Money ist mir eigentlich klar. Wie setze ich die in die SQL dazu?

Wie siehts eigentlich mit einem Ja/Neit Wert aus?

Wie soll ich das mir 'Clear' lösen?

Naja, viele fragen aber ich will es ja lernen. Ich werde mir noch diese Woche das Buch 'Datenbankprogrammieren in Delphi 6 kaufen'. Was hälst du davon? Ich glaube, dann wird mir auch einiges klar. Find ich in diesem Buch auch solche Beispiele, wie ich sie in diesem Forum poste?

MrSpock 17. Sep 2002 07:39

Hallo m-werk,

das mit dem Buch ist eine gute Idee. Ich denke, wenn man Datenbankprogrammierung benötigt, sollte man den Grundlagen anfangen und da ist ein gutes Buch viel Wert. Man kann dann auch später gewisse Details einfach noch einmal nachschlagen.

Zitat:

also geht das einstellen vom Format wie z.B. 'Standartzahl oder Euro' nicht.
Solange du über die BDE auf eine Datenbank zugreifst, musst du dich mit "Loacal SQL" begnügen, was eine Untermenge des ANSI-SQL Standards ist. Die Angabe, wie Access Daten aus der Datenbank in einem Formular oder der Tabellenansicht darstellt, kann nicht über SQL festgelegt werden, sondern nur über die Oberfläche selbst. Zeigst du aber den Inhalt der DB in Delphi Komponenten an, kannst du dort das Format z.B. über die Eigenschaft DisplayFormat (siehe Online Hilfe) einstellen.

Zitat:

Was bedeutet FLOAT und MONEY?
Money ist mir eigentlich klar. Wie setze ich die in die SQL dazu?
FLOAT bedeutet einfach nur Gleitkommazahl. Es gibt auch das Format FLOAT(x,y) mit dem man die Genauigkeit der zu speichernden Daten angeben kann. Es ist aber leider so, dass der SQL String an die Datenbank geschickt wird und die diesen dann selbst umsetzt. Und das bedeutet, dass grundsätzlich die Umsetzung unterschiedlich sein kann (z.B. Genauigkeit). Money soll eigentlich 2 Nachkommastellen haben, dBase ersetzt es aber durch Numeric(20,4). Was ich damit sagen will, ist: Probier das Ganze mal mit Access aus und schau dir an, wie Access z.B. MONEY oder FLOAT umsetzt. FLOAT und MONEY sind Typen, die du syntaktisch anstelle von NUMERIC oder CHAR(20) in den o.g. Beispielen benutzen kannst.

Zitat:

Wie siehts eigentlich mit einem Ja/Neit Wert aus?
Das wäre der Typ BOOLEAN. Aber auch hier gilt: Nachprüfen, was die Datenbank daraus macht!

Zitat:

Wie soll ich das mir 'Clear' lösen?
Angenommen deine TQuery heißt qryInsert, dann schreibst du z.B.:

Code:
for i := 1 to 9 do
begin
   qryInsert.Close;
   qryInsert.SQL.Clear;
   qryInsert.SQL.Add(InsertStr[i]);
   qryInsert.ExecSQL
end;
Dabei sollte der Array InsertStr die neun verschiedenen SQL Statements enthalten, also:

InsertStr[1] := 'ALTER TABLE Kinder ADD XY NUMERIC';
InsertStr[2] := ...

m-werk 17. Sep 2002 08:23

Also sollte der SQL-String in der ADOQuery so aussehen:

InsertStr[1] := 'ALTER TABLE Kinder ADD XY NUMERIC';
InsertStr[2] := 'ALTER TABLE ....
InsertStr[3] := ... usw.

und der Code für den Button sieht so aus, wie bei dir beschrieben.

Dann muß ich nur noch die DBEdit-Felder so Formatieren, wie ich sie berauche.

Kann ich die DBEdit-Felder schon in mein Programm einbauen obwohl zuerst in der Datenbank selbst die Felder noch gar nicht vorhanden sind?

Ich möchte es ja so machen, dass wenn ein User das Programm installiert, er dann zuerst das DB-Update Button klickt damit die Datenbank auf den neuesten Stand ist.
Und jetzt kann der User auch schon in die Felder was eintragen, die neu sind.
Die Felder sind aber ja schon vorher drinn.

Kann ich das so ohneweiters machen, oder gibts da einen konflikt, weil ja die Felder in der Datenbank noch nicht existieren?[/code]

MrSpock 17. Sep 2002 09:39

Hallo m-werk,

damit es nicht so kompliziert wird, würde ich ein kleines Programm schreiben, dass nur die Tabelle anpasst, d.h. die Felder hinzufügt.

Das eigentliche Programm sollte dann die bereits angepasste Tabelle voraussetzen.

Ansonsten ist deine vorgeschlagene Vorgehensweise korrekt.

m-werk 17. Sep 2002 18:12

Ich hab jetzt alles so gemacht. Ich hab ein eigenes Programm erstellt. Nun hab ich probleme mit dem Button.

Code:
procedure TForm1.Button1Click(Sender: TObject);
var i : string;
begin
  for i := 1 to 4 do
  begin
    DataModule2.ADOQuery1.Close;
    DataModule2.ADOQuery1.SQL.Clear;
    DataModule2.ADOQuery1.SQL.Add(InsertStr[i]);
    DataModule2.ADOQuery1.ExecSQL
end;
Es kommt immer die Meldung:
FOR-Schleifenvariable muß von ordinalem Typ sein
Undefinierter Bezeichner: 'InsertStr'

Was hab ich da vergessen?


Weiters: Wie kann ich es anstellen, dass das Programm automatisch beim 1. Start des eigentlichen Programmes gestartet wird, und dann nie wieder.

Denn wenn einmal die Felder in der DB sind, dann werd ich nicht nochmal das Programm starten. Wie muß ich da vorgehen?

MrSpock 18. Sep 2002 06:26

Hallo m-werk,

du hast ja nur eine Schleife :wink: , und dort steht nur eine Variable und die heißt i. I darf nicht als String, sondern muss als Integer (oder SmallInt) deklariert werden. Dann funktioniert es.

Zum Thema automatisches Starten guckst du hier

m-werk 19. Sep 2002 08:51

Das mit dem Start ist mir schon bekannt, aber ich möchte ja, dass diese exe-Datei nur beim 1. Start erfolgt. Mit diesem Code erfolgt sie bei Jedem Start.

MrSpock 19. Sep 2002 10:06

Hallo m-werk,

frag doch in der Schleife nach, ob das Feld existiert:

Code:
procedure TForm1.Button1Click(Sender: TObject);
var i : string;
begin
  for i := 1 to 4 do
  begin
    if Not DataModule2.TheTable.FindField(FeldName[i]) then
    begin
       DataModule2.ADOQuery1.Close;
       DataModule2.ADOQuery1.SQL.Clear;
       DataModule2.ADOQuery1.SQL.Add(InsertStr[i]);
       DataModule2.ADOQuery1.ExecSQL
     end
   end
end;
Dabei ist FeldName ein Array, der die Namen der neuen Felder enthält und TheTable der Name des Tabellenobjekts, das auf die zu ändernde Tabell zeigt. Dann kann das Programm beliebig oft gestartet werden, ohne etwas kaputt zu machen. Ich würde aber noch eine Meldung ausgeben, wieviele Felder hinzugefügt worden sind.

m-werk 19. Sep 2002 12:01

Das ist super. Muß ich gleich, wenn ich wieder mal zeit habe, das ausprobieren.

Eine Frage noch?
Was beideutet ARRAY?
Wie meinst du das mit ARRAY?

MrSpock 19. Sep 2002 12:37

Hallo m-werk,

genauso wie bei InsertStr.

Du kannst es als Variable oder als typisierte Konstante deklarieren.

Also z.B.:

Code:
const
   FeldName : array[1..4] of String = ('Kinder', 'Geld', 'BlaBla', 'Hallo');

m-werk 19. Sep 2002 12:41

Ahh, so etwas ähnliches habe ich bei einer Berechnung gemacht:

Edit1 + Edit2 - Edit3 usw.

Code:
const
   FeldName : array[1..4] of String = ('Kinder', 'Geld', 'BlaBla', 'Hallo');
Das was in der Klammer steht, sind die Datenfelder und wo setze ich diesen Code ein?

MrSpock 19. Sep 2002 13:49

Hallo m-werk,

irgendwo im Sichtbereich der Stelle, an der du darauf zugreifst.

Also z.B.:


Code:
procedure TForm1.Button1Click(Sender: TObject);
const
   FeldName : array[1..4] of String = ('Kinder', 'Geld', 'BlaBla', 'Hallo');
var i : string;
begin
  for i := 1 to 4 do
  begin
    if Not DataModule2.TheTable.FindField(FeldName[i]) then
    begin
       DataModule2.ADOQuery1.Close;
       DataModule2.ADOQuery1.SQL.Clear;
       DataModule2.ADOQuery1.SQL.Add(InsertStr[i]);
       DataModule2.ADOQuery1.ExecSQL
     end
   end
end;
Greifst du auch noch an anderen Stellen darauf zu, dann musst du die Deklaration z.B. for die Klassendeklaration der unit schreiben.

m-werk 20. Sep 2002 17:32

Hi, ich komm einfach nicht dahinter:

Code:
procedure TForm1.Button1Click(Sender: TObject);
const
   FeldName : array[1..4] of String = ('Rueckzahlung', 'Kreditwaehrung', 'Zinssatz1', 'Zinssatzgebunden');
   var i : Integer;
begin
  for i := 1 to 4 do
  begin
    if Not DataModule2.ADOSFinanzierung.FindField(FeldName[i]) then
    begin
       DataModule2.ADOQuery1.Close;
       DataModule2.ADOQuery1.SQL.Clear;
       DataModule2.ADOQuery1.SQL.Add(InsertStr[i]);
       DataModule2.ADOQuery1.ExecSQL
     end;
   end;
end;
So sieht jetzt mein code aus.

Nun kommen aber wieder folgende Fehlermeldungen:
[Fehler] DBUpdate.pas(42): Operator ist auf diesen Operandentyp nicht anwendbar
Dies kommt bei der zeile:
if Not DataModule2.ADOSFinanzierung.FindField(FeldName[i]) then

[Fehler] DBUpdate.pas(46): Undefinierter Bezeichner: 'InsertStr'

Was ist da jetzt noch los?

MrSpock 20. Sep 2002 19:02

Hallo m-werk,

OK, war mein Fehler. FindField gibt kein True oder False zurück, sondern das Feld, sofern es gefunden wurde, sonst NIL.

Der Code muss also so aussehen:

Code:
...
if DataModule2.ADOSFinanzierung.FindField(FeldName[i])=NIL then
...
Naja und der 2. Fehler ist doch offensichtlich :roll:

Na wo is denn da der InsertStr Array :mrgreen:

m-werk 23. Sep 2002 16:42

Hi, ist der Code nun richtig?

Code:
procedure TKundendaten.Button3Click(Sender: TObject);
const
   FeldName : array[1..4] of String = ('Rueckzahlung', 'Kreditwaehrung', 'Zinssatz1', 'Zinssatzgebunden');
   var i : Integer;
       InsertStr : String;
begin
  for i := 1 to 4 do
  begin
    if DM.ADOSFinanzierung.FindField(FeldName[i])=NIL then
    begin
       DM.QueryFinanzierung.Close;
       DM.QueryFinanzierung.SQL.Clear;
       DM.QueryFinanzierung.SQL.Add(InsertStr[i]);
       DM.QueryFinanzierung.ExecSQL
     end;
   end;
end;
Wenn ich jetzt den Button klicke, dann kommt folgende Fehlermeldung:
Zugriffsverletzung bei Adresse 004FE3E7 in Modul 'Kundenverwaltung.exe'. Lesen von Adresse 00000000.

Ich hab mir auch die Datenbank dann angesehen, und hab aber keine Felder gefunden, die neu sein sollten.

MrSpock 23. Sep 2002 19:25

Hallo m-werk,

wenn du InsertStr lokal deklarierst wie in einem Code gezeigt, dann musst du natürlich auch die Werte für InsertStr[1] bis InsertStr[4] setzen. Du könntest das ebenfalls als typisierte Konstante machen. Oder durch 4 Zuweisungen, wie irgendwo oben beschrieben.

m-werk 24. Sep 2002 07:12

Hi, ich bin jetzt leider mit deiner Antwort nicht zurechtgekommen. Hab nicht ganz kapiert, wie du das meinst!

MrSpock 24. Sep 2002 12:12

Hallo m-werk,

guckst du hier:

Code:
procedure TKundendaten.Button3Click(Sender: TObject);
const
   FeldName : array[1..4] of String = ('Rueckzahlung', 'Kreditwaehrung', 'Zinssatz1', 'Zinssatzgebunden');

   InsertStr : array[1..4] of String =
               ('ALTER TABLE Kinder ADD XY NUMERIC',
                'ALTER TABLE Kinder ADD ...',
                 ...);
var
   i : Integer;  
begin
  for i := 1 to 4 do
  begin
    if DM.ADOSFinanzierung.FindField(FeldName[i])=NIL then
    begin
       DM.QueryFinanzierung.Close;
       DM.QueryFinanzierung.SQL.Clear;
       DM.QueryFinanzierung.SQL.Add(InsertStr[i]);
       DM.QueryFinanzierung.ExecSQL
     end;
   end;
end;

m-werk 24. Sep 2002 12:44

Ich habe auch in der Query so einen SQL-String

ALTER TABLE.....


Bleibt dieser Bestehen?

MrSpock 24. Sep 2002 16:20

Hallo m-werk,

wenn die Query nur durch Drücken des Schalters Button3 ausgeführt wird, wird der String dort überschrieben. Dann kann das SQL Feld leer bleiben (macht aber auch nix, wenn es nicht leer ist :mrgreen: ).

m-werk 25. Sep 2002 15:22

Danke für die Antwort.

Was ist eigentlich, wenn ich später wieder Felder in die Datenbank einfügen möchte?

Kann ich da ganz normal den Code erweitern und es werden dann nur die Felder eingefügt, die noch nicht existieren oder muß ich da was neu machen?

MrSpock 25. Sep 2002 16:14

Hallo m-werk,

kannste einfach erweitern :mrgreen: .

m-werk 25. Sep 2002 19:21

Hi, ich hab bemerkt, dass ich das aber nicht einfach so erweitern kann.

Ich habe zuerst 4 Felder in die Datenbank eingefügt. Das hat prima geklapt.

Nun aber habe ich den Code um 1 Feld erweitert. Das klapt aber nicht.

Code:
procedure TKundendaten.Button3Click(Sender: TObject);
const
   FeldName : array[1..5] of String = ('Rueckzahlung', 'Kreditwaehrung', 'Zinssatz1', 'Zinssatzgebunden', 'Aufschlag');
   InsertStr : array[1..5] of String =
               ('ALTER TABLE Finanzierung ADD Rueckzahlung CHAR(30)',
                'ALTER TABLE Finanzierung ADD Kreditwaehrung CHAR(10)',
                'ALTER TABLE Finanzierung ADD Zinssatz1 CHAR(10)',
                'ALTER TABLE Finanzierung ADD Zinssatzgebunden CHAR(10)',
                'ALTER TABLE Finanzierung ADD Aufschlag FLOAT');
   var i : Integer;
begin
  for i := 1 to 5 do
  begin
    if DM.ADOSFinanzierung.FindField(FeldName[i])=NIL then
    begin
       DM.QueryFinanzierung.Close;
       DM.QueryFinanzierung.SQL.Clear;
       DM.QueryFinanzierung.SQL.Add(InsertStr[i]);
       DM.QueryFinanzierung.ExecSQL
     end;
   end;
end;
Wenn ich im Programm nun den Button anklicke, kommt folgende Fehlermeldung:

Feld 'Rueckzahlung' ist bereits in der Tabelle 'Finanzierung' vorhanden.

Kann man das umgehen, so dass wenn man den Button drückt diese Meldung nicht mehr kommt?
Es kann ja sein, dass einige User einigemale auf den Button klicken.
Da soll einfach nichts geschehen, wenn schon die Felder in der DB stehen.

Und wenn welche dazukommen, dann sollen die einfach dazukommen. Die anderen sollen dabei nicht angegriffen werden.

MrSpock 25. Sep 2002 21:13

Hallo m-werk,

das ist verwunderlich, weil wir ja extra die Abfrage FindField benutzen, um ein Feld nicht mehrfach hinzuzufügen.

Ich könnte mir aber vostellen, dass es da ein Problem gibt, weil ja die ADOFinanzierung Tabelle geöffnet ist, und du dann versuchst ein Feld hinzuzufügen. Versuche doch einmal:

Code:
    if DM.ADOSFinanzierung.FindField(FeldName[i])=NIL then
    begin
       DM.ADOSFinanzierung.Close;
       DM.QueryFinanzierung.Close;
       DM.QueryFinanzierung.SQL.Clear;
       DM.QueryFinanzierung.SQL.Add(InsertStr[i]);
       DM.QueryFinanzierung.ExecSQL;
       DM.ADOSFinanzierung.Open;
     end;
Als zweite mögliche Ursache könnte ich mir vorstellen, dass es ein Problem gibt, wenn du die Felder der bereits bestehende Tabelle über den Feldeditor hinzugefügt hast. Es könnte sein, dass FindField dann die neuen Felder nicht findet. Ich meine mich erinnern zu können, dass das bei FieldByName auch so ist, dass die nicht eingefügten Felder nicht gefunden werden, obwohl sie ja in der zugrundeliegenden Datenmenge enthalten sind.

MrSpock 25. Sep 2002 21:41

Hallo m-werk,

ich glaube ich habe den Fehler gefunden. Die Tabelle muss natürlich für die Abfrage FindField geöffnet sein, darf aber dann für das Hinzufügen der Felder nicht geöffnet sein, also:

In der Schleife:
Code:
    DM.ADOSFinanzierung.Open;
    if DM.ADOSFinanzierung.FindField(FeldName[i])=NIL then
    begin
       DM.ADOSFinanzierung.Close;
       DM.QueryFinanzierung.Close;
       DM.QueryFinanzierung.SQL.Clear;
       DM.QueryFinanzierung.SQL.Add(InsertStr[i]);
       DM.QueryFinanzierung.ExecSQL;
     end;
So hat es bei mir funktioniert. Übrigens ist die o.g. Annahme richtig, dass die alten Felder nicht über den Feldeditor hinzugefügt worden sein dürfen. Das heißt also, dass du ggf. doch ein zweites "Update" Programm erstellen musst.

m-werk 26. Sep 2002 18:14

Hi, ich habe jetzt den code so erstellt, wie oben beschrieben.

LEIDER hab ich noch immer das gleiche problem.

Wenn die Felder in der Datenbank nicht existieren, dann werden sie mit dem klick hinzugefügt. Das klapt zur Zeit prima. Aber wenn ich nochmals den Button anklicke, dann kommt wieder die Fehlermeldung, die ich oben schon genannt habe.

Weiters wollte ich dann im Formular ein Edit einbauen, dass auf die neuen Datenfelder zugreifen soll. Das hat nicht funktioniert. Ich habe die DataSource zugeordnet, dann wollte ich das Feld zuordnen aber es scheint kein neues Feld auf.
Ich kann diese nicht zuordnen, obwohl diese in der Datenbank schon existieren.

Was ist da los?

MrSpock 26. Sep 2002 19:25

Hallo m-werk,

ich vermute, du hast die "alten" Felder der Tabelle über den Feldeditor in das Programm eingefügt. Ist das so?

m-werk 26. Sep 2002 19:49

Hi, wie meinst du damit?

Ich habe die Felder, welche ich eingefügt habe mit dem Code, der oben beschrieben ist, eingefügt.

Ich habe dann die ADOSFinanzierung mit doppelklick geöffnet und wollte dann 'Felder hinzufügen' anklicken, da kam die Meldung:

Fehler bei der Authentifizierung.

Ich hab keine Ahnung, was dass wieder heißt.

Sonst hab ich nichts gemacht.

m-werk 30. Sep 2002 16:33

Hi Leute, hat keiner von euch eine Idee, wie Ich das obrige Problem lösen kann?

Wäre euch zu dank verpflichtet, wenn ihr mir helfen könnt!

MrSpock 30. Sep 2002 20:38

Hallo m-werk,

was ich meine ist folgendes. Du hast ja bereits ein Programm, was auf die Tabelle ADOSFinanzierung mit der alten Struktur zugreift. Diese alten Felder hast du wahrscheinlich über einen Doppelklick auf das Tabellensymbol als TField - Objekte eingefügt. Wenn du jetzt neue Felder hinzufügst, werden diese zunächst korrekt der Tabelle hinzugefügt. Das Programm, was ich oben beschrieben habe nutzt die Funktion FindField, um festzustellen, ob die "neuen" Felder in der Tabelle gefunden werden können. Das Problem ist aber, dass dadurch, dass die alten Felder bereits hinzugefügt wurden, die Funktion FindField die neuen Felder nicht sehen kann.

Ein Authentisierungsfehler tritt normalerweise auf, wenn du auf die Tabelle nicht zugreifen kannst, z.B. weil das Passwort nicht stimmt.

Deshalb war mein Vorschlag, ein kleines Programm zu schreiben, bei dem noch keine Felder über den Feldeditor eingefügt wurden. Das Programm hat nur die Tabelle und einen Button, der die ALTER TABLE Statements ausführt. Das sollte dann funktionieren.

m-werk 1. Okt 2002 18:55

Hi, ich glaub jetzt hab ich die Ursache für den Fehler gefunden.

Bei mir ist es so, dass ich bei der ConnectionString im Objektinspektor nichts drinn stehen habe. Das heist, ich kann, wenn ich im Programmiermodus bin, nichts neues erstellen.

Ich rufe erst die Connectionstring beim start des Programmes auf. Ich habe das deshalb gemacht, da ich den Path von der Datenbank in die Registry schreibe und von dortaus auch ablese. (Das hat so seine Gründe).
Und ein Passwort habe ich ja auch in der Connectionstring.

So sieht der Code aus:
Code:
procedure TDM.DataModuleCreate(Sender: TObject);
var REG:TRegistry;
    a:string;
begin
  REG:=Tregistry.create;
  try
    REG.RootKey := HKEY_CURRENT_USER;
    REG.Access := KEY_READ;
    if REG.OpenKeyReadOnly('Software\AriusDB\SettingsDB') then
    begin
      try
        a:=REG.ReadString('DBPath');
        if not DirectoryExists(a) then
        begin
          MessageBox(0,PChar(SysErrorMessage(GetLastError)+#13#13+'Datenbank wurde nicht gefunden! Wert: '+IntToStr(GetLastError)),'Fehler!',MB_ICONERROR or MB_OK);
        end;
      except
        MessageBox(0,PChar(SysErrorMessage(GetLastError)+#13#13+'Datenbank wurde nicht gefunden! Wert: '+IntToStr(GetLastError)),'Fehler!',MB_ICONERROR or MB_OK);
      end;
    end
    else
    begin
      MessageBox(0,PChar(SysErrorMessage(GetLastError)+#13#13+'Datenbank wurde nicht gefunden! Wert: '+IntToStr(GetLastError)),'Fehler!',MB_ICONERROR or MB_OK);
    end;
  finally
    FreeAndNil(REG);
  end;
  ADOConnection1.ConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;Data Source=' +
                          a + '\Kundendaten.mdb;Mode=ReadWrite;Extended Properties="";Jet OLEDB:System database="";Jet OLEDB:Registry Path="";Jet OLEDB:Database Password=passwort;'+
                         'Jet OLEDB:Engine Type=5;Jet OLEDB:Database Locking Mode=1;Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Global Bulk Transactions=1;Jet OLEDB:New Database Password="";Jet OLEDB:Create System Database=False;' +
                         'Jet OLEDB:Encrypt Database=False;Jet OLEDB:Don''t Copy Locale on Compact=False;Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=False';
  ADOConnection1.Connected := TRUE;
  DM.ADOSHaupt.Open; DM.ADOSKinder.Open; DM.ADOSGeschaeft.Open; DM.ADOSFinanzierung.Open;
  DM.ADOSHaushalt.Open; DM.ADOSAnlageprofiel.Open; DM.ADOSEmpfehlung.Open; DM.ADODataSet1.Open;
  DM.ADODataSet2.Open;
end;
Kann ich das auch anders machen, so dass ich im Programmiermodus auch aktuell bin?


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:25 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