AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Mit ZEOS-Tables Inserts durchführen
Thema durchsuchen
Ansicht
Themen-Optionen

Mit ZEOS-Tables Inserts durchführen

Ein Thema von UGrohne · begonnen am 11. Mai 2005 · letzter Beitrag vom 13. Mai 2005
Antwort Antwort
UGrohne

Registriert seit: 12. Dez 2002
Ort: Pliezhausen
65 Beiträge
 
Delphi 7 Professional
 
#1

Mit ZEOS-Tables Inserts durchführen

  Alt 11. Mai 2005, 13:31
Datenbank: Firebird • Version: 1.5 • Zugriff über: ZEOS
Moin,
ich bin gerade dabei eine Software von BDE auf Firebird mit Hilfe von ZEOS umzustellen. In der Anwendung wurden einige TTables verwendet (gekapselt in davon abgeleiteten Klassen). Diese habe ich dann umgeschrieben, sodass sie von TZTable abgeleitet sind und bisher einige Dinge reingepackt, die unterschiedlich waren.
Ich will also nur durch Veränderung dieser Komponente auf ZEOS umstellen, die Anwendung selbst soll möglichst nicht angefasst werden, da dies viel Aufwand beudeten würde.

Zu den Features, die ich einbauen musste gehört die automatische Erstellung des UpdateSQL-Objekts, damit das ZTable auch Daten ändern kann. Das funktioniert auch schon (habs in OnAfterOpen reingepackt und die SQL-Statements erstellen lassen).

Und nun zum Problem: In der Anwendung wird ein neuer Datensatz eingefügt:
Delphi-Quellcode:
      table.Insert;
      table.FieldByName('AdrTyp').Value := 3;
      table.FieldByName('AdrArt').Value := 1;
      table.FieldByName('Nummer').Value := NeueNummer;
      table.Post;
Jetzt gibt es ein Feld Name1 das in der Datenbank als NotNull erstellt wurde. Aufgrund meiner UpdateSQL-Scripte wird jetzt natürlich folgender SQL-Code erzeugt:
INSERT INTO tabelle (AdrTyp,AdrArt,Nummer,Name1) VALUES (3,1,99999,NULL); da ja alle Felder darin vorkommen. Das läuft aber natürlich auf einen Fehler, weil Name1 nicht NULL sein darf.

Ich muss also vor dem Insert (bzw OnBeforePost) die SQL-Skripte erneut schreiben und zwar vor allem das Insert-Statement und dort nur die Felder eintragen, die geändert wurden.

Hat jemand eine Ahnung, wie ich das machen kann?

Mit folgendem Code hab ichs mal probiert:
Delphi-Quellcode:
  for i:=0 to Fields.Count-1 do begin
    //***Update-Object konfigurieren***
    if Fields[i].FieldKind<>fkData then //Abbruch, wenn kein physisches DB-Feld
      Continue;
    //Key-Felder
    if (pfInKey IN Fields[i].ProviderFlags) then begin
      if keysql<>'then
        keysql:=keysql+' and ';
      keysql:=keysql+Fields[i].FieldName+'= :OLD_'+Fields[i].FieldName;
      end;
    //Alle Felder für alternative WHERE-Bedingung
    if altkeysql<>'then
      altkeysql:=altkeysql+' and ';
    altkeysql:=altkeysql+Fields[i].FieldName+'= :OLD_'+Fields[i].FieldName;
    //Felder und Werte für UPDATE-Statement
    if modsql<>'then
      modsql:=modsql+', ';
    modsql:=modsql+Fields[i].FieldName+'= :'+Fields[i].FieldName;
    if (Fields[i].OldValue<>Fields[i].NewValue) or (not Fields[i].IsNull) then begin //kritischer Punkt
      //Werte für Insert-Statement
      if inssql<>'then
        inssql:=inssql+', ';
      inssql:=inssql+':'+Fields[i].FieldName;
      //Felder für Insert-Statement
      if insfields<>'then
        insfields:=insfields+', ';
      insfields:=insfields+Fields[i].FieldName;
      end;
    end;

  if keysql='then keysql:=altkeysql;
  UpdateObject.DeleteSQL.Text:='DELETE FROM '+TableName+' WHERE '+keysql+';';
  UpdateObject.ModifySQL.Text:='UPDATE '+TableName+' SET '+modsql+' WHERE '+keysql+';';
  UpdateObject.InsertSQL.Text:='INSERT INTO '+TableName+' ('+insfields+') VALUES ('+inssql+');';
Nur sind in diesem Fall OldValue und NewValue gleich ...
Uwe
Lieber 3 Stunden Vorlesung, als gar kein Internetzugang
  Mit Zitat antworten Zitat
UGrohne

Registriert seit: 12. Dez 2002
Ort: Pliezhausen
65 Beiträge
 
Delphi 7 Professional
 
#2

Re: Mit ZEOS-Tables Inserts durchführen

  Alt 11. Mai 2005, 14:46
Ich habe eben bei ZEOS auf Sourceforge entdeckt, dass die Feldfunktion "IsNull" einen Bug hatte und hab das bei mir mal nachgeprüft. Der bug bezog sich darauf, dass wenn ein Stringfeld als Wert einen leeren String hatte (also "") und nicht NULL, dann gab IsNull trotzdem true zurück, obwohl es ja nicht stimmt.

Laut Kommentar sollte dieser Bug aber schon gefixt worden sein in 6.5.1, aber ich habe ihn immer noch.
Und dann erklärt sich das alles ja auch, denn der Feldwert für name1 stimmt, es ist ein leerer String, aber da IsNull ja true zurück gibt, wird die Komponente wohl den Wert beiseite schieben und einfach nur NULL als Wert in die SQL-Anweisung schreiben, oder nicht?

Wie kann ich diesen Fehler korrigieren, weiß da jemand schon den Bugfix dazu?
Uwe
Lieber 3 Stunden Vorlesung, als gar kein Internetzugang
  Mit Zitat antworten Zitat
Benutzerbild von Sharky
Sharky

Registriert seit: 29. Mai 2002
Ort: Frankfurt
8.252 Beiträge
 
Delphi 2006 Professional
 
#3

Re: Mit ZEOS-Tables Inserts durchführen

  Alt 11. Mai 2005, 16:54
Zitat von UGrohne:
... Wie kann ich diesen Fehler korrigieren, weiß da jemand schon den Bugfix dazu?
Hai UGrohne,

hier lesen mindestenz 2 Entwickler der Zeos-Lib mit. Ich hoffe das sie Dir eine Antwort auf deine Frage geben könnne?
Stephan B.
"Lasst den Gänsen ihre Füßchen"
  Mit Zitat antworten Zitat
UGrohne

Registriert seit: 12. Dez 2002
Ort: Pliezhausen
65 Beiträge
 
Delphi 7 Professional
 
#4

Re: Mit ZEOS-Tables Inserts durchführen

  Alt 11. Mai 2005, 16:56
Zitat von Sharky:
Zitat von UGrohne:
... Wie kann ich diesen Fehler korrigieren, weiß da jemand schon den Bugfix dazu?
Hai UGrohne,

hier lesen mindestenz 2 Entwickler der Zeos-Lib mit. Ich hoffe das sie Dir eine Antwort auf deine Frage geben könnne?
Das hoffe ich auch. Ich hab inzwischen auch die entsprechende Person angeschrieben, die auf Sourceforge den Bugreport geclosed hat.
Uwe
Lieber 3 Stunden Vorlesung, als gar kein Internetzugang
  Mit Zitat antworten Zitat
Benutzerbild von mschaefer
mschaefer

Registriert seit: 4. Feb 2003
Ort: Hannover
2.032 Beiträge
 
Delphi 12 Athens
 
#5

Re: Mit ZEOS-Tables Inserts durchführen

  Alt 11. Mai 2005, 17:31
Hm, Moin,

also irgendwie kann ich mich der Ahnung nichr entziehen, dass dies hier kein Problem von ZEOS ist. Du fügst mit Insert einen Datensatz ein und belegst ein Feld nicht, das den Wert Null nicht enthalten darf. Enweder darf der Datensatz nicht geinserted werden, wenn der Name nicht angegen ist oder Du solltest diesen mit einem Dummywert vorbelegen, in BeforInsert.

Grüße // Martin
Martin Schaefer
  Mit Zitat antworten Zitat
UGrohne

Registriert seit: 12. Dez 2002
Ort: Pliezhausen
65 Beiträge
 
Delphi 7 Professional
 
#6

Re: Mit ZEOS-Tables Inserts durchführen

  Alt 11. Mai 2005, 20:26
Nein, ich hab mit Hilfe des obigen Codes auch geprüft, wie das Ergebnis aussieht.
Und zwar indem ich mir bei jedem Feld Field[i].NewValue und OldValue anschaue und dann IsNull überprüfe. Und bei Name1 bekomme ich: '' und bei Name2 (als Beispiel) null. Aber bei IsNull steht bei beiden true.

Die Standardwerte (defaults der Datenbank) hat die ZEOS-Komponente anscheinende gut übernommen, nur IsNull scheint das Problem zu sein.
Uwe
Lieber 3 Stunden Vorlesung, als gar kein Internetzugang
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.017 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#7

Re: Mit ZEOS-Tables Inserts durchführen

  Alt 12. Mai 2005, 10:15
Hallo UGrohne,

ich hätte zunächst mal einige Fragen zum besseren Verständnis:

- warum benutzt du das UpdateObject von TZTable? (auch ohne ist TZTable eine bidirektionale Datenmenge)
- warum belegst du ein Feld, was als NOT NULL definiert ist nicht mit einem Wert? (Ist doch klar, dass dann ein Fehler hochkommt)

Die Benutzung der Funktion TField.IsNull hat eigentlich nichts mit Zeos zu tun, da diese in der Unit DB.pas definiert ist.

Ich würde mir gerne einmal deinen Fehlerfall anschauen. Es wäre also nett von dir, wenn du mir ein kleines Testprojekt (inklusive Testdatenbank) zukommen lassen könntest, anhand dessen man den Fehler nachvollziehen könnte.

MfG
Stevie
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
UGrohne

Registriert seit: 12. Dez 2002
Ort: Pliezhausen
65 Beiträge
 
Delphi 7 Professional
 
#8

Re: Mit ZEOS-Tables Inserts durchführen

  Alt 13. Mai 2005, 09:20
Zitat von Stevie:
- warum benutzt du das UpdateObject von TZTable? (auch ohne ist TZTable eine bidirektionale Datenmenge)
- warum belegst du ein Feld, was als NOT NULL definiert ist nicht mit einem Wert? (Ist doch klar, dass dann ein Fehler hochkommt)
Erstmal zu Deinen Frage:
1. Das habe ich verwendet, weil ich davon ausgegangen bin, dass es sich wie bei TIBQuery verhält, also dass ich diese zusätzliche Kompo brauche, damit Änderungen möglich sind. Da Du mir ja jetzt aber auch gesagt hast, dass dem nicht so ist, hat sich das Problem in Luft aufgelöst.

2. Weil es in diesem Fall mit dem Default-Wert in der Datenbank befüllt werden soll. Ich bin davon ausgegangen, dass die Kompo dieses Feld (wenn es nicht verwendet wird) beim UPDATE auch auslässt, aber da hab ich nicht lang genug nachgedacht. Denn wenn ich selbst die Statements (mit Hilfe von TZUpdateSQL) bereitgestellt habe, dann sollte die Kompo diese ja nicht mehr verändern. Somimt hätte das niemals so funktioniert.

Da ich diese Kompo ja jetzt aber rauslassen kann und es so jetzt funktioniert, ist alles in Butter.

Auch der Bug, den ich gefunden hatte, lag wohl am hiesigen Debugger, denn zu Hause und jetzt hier zeigt er das korrekte Verhalten, weiß der Geier warum auf einmal ...

Vielen Dank also fürs Heben des Steins von meiner Leitung
Uwe
Lieber 3 Stunden Vorlesung, als gar kein Internetzugang
  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 16:25 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