![]() |
Datenbank: Firebird • Version: 1.5 • Zugriff über: ZEOS
Mit ZEOS-Tables Inserts durchführen
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:
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:
table.Insert;
table.FieldByName('AdrTyp').Value := 3; table.FieldByName('AdrArt').Value := 1; table.FieldByName('Nummer').Value := NeueNummer; table.Post;
SQL-Code:
da ja alle Felder darin vorkommen. Das läuft aber natürlich auf einen Fehler, weil Name1 nicht NULL sein darf.
INSERT INTO tabelle (AdrTyp,AdrArt,Nummer,Name1) VALUES (3,1,99999,NULL);
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:
Nur sind in diesem Fall OldValue und NewValue gleich ...
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+');'; |
Re: Mit ZEOS-Tables Inserts durchführen
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? |
Re: Mit ZEOS-Tables Inserts durchführen
Zitat:
hier lesen mindestenz 2 Entwickler der Zeos-Lib mit. Ich hoffe das sie Dir eine Antwort auf deine Frage geben könnne? |
Re: Mit ZEOS-Tables Inserts durchführen
Zitat:
|
Re: Mit ZEOS-Tables Inserts durchführen
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 |
Re: Mit ZEOS-Tables Inserts durchführen
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. |
Re: Mit ZEOS-Tables Inserts durchführen
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 |
Re: Mit ZEOS-Tables Inserts durchführen
Zitat:
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 ;-) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:33 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