Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Problem mit NULL-Werten (https://www.delphipraxis.net/2653-problem-mit-null-werten.html)

Hansa 31. Jan 2003 12:45


Problem mit NULL-Werten
 
Hi,

ich übernehme hier Daten aus einer Textdatei in eine Interbase Datenbank, bzw. will ich in diesem Fall bisher nicht vorhandene Felder mit einem gültigen Wert vorbesetzen:
Code:
   
    LiefDS.FindField ('ABHOLUNG').AsString := '0';
    LiefDS.FindField ('BANKEINZUG').AsString := '0';
showmessage ('*'+LiefDS.FindField ('BANKEINZUG').AsString+'*');
Diese beiden Felder sind definiert als CHAR (1). Sehe ich mir in der Konsole die Werte an, steht bei dem ersten wirklich 0 drin, bei dem zweiten aber NULL ! Ändere ich das ganze von '0' auf '1' steht bei dem ersten 1 und bei dem zweiten wieder NULL !!! :shock: Sag mir mal einer, wie so etwas möglich ist. Die Showmessage zeigt '*0*' an, wegen der *chen sehe ich, daß da nicht noch andere Zeichen vorhanden sind.

Gruß
Hansa

xbu58 31. Jan 2003 18:47

hallo Hansa

Hast Du ev. auf der Tabelle einen Trigger, der den Wert zurücksetzt?

Gruss
Xaver

Hansa 31. Jan 2003 18:58

Gute Idee !

die Trigger darf ich nicht aus den Augen verlieren, aber ich habe nur einen für die IDs gesetzt. Die Felder, die ich als Beispiel genommen habe sind relativ unwichtig, der Effekt aber nicht. Die Table, bei der mir das auffiel hat ca. 30 Felder, aber ich habe welche mit 300 oder noch mehr, soll ich die jetzt alle überprüfen, bei zig-tausend Datensätzen ? Bin gerade dabei, alle Programme neu zu compilieren und laufen zu lassen, dauert ewig, na denn :cheers: . Werde nachher mal sehen.

Gruß
Hansa

xbu58 31. Jan 2003 19:07

Na ja war so eine Idee. Bin selber einmal in eine solche Falle gelaufen.

Hier noch eine Idee. Hast Du ev. eine Maske auf das Feld gelegt?

Gruss
Xaver

PS: Ich glaube Du trinkst etwas zu viel :cheers: oder hast Du einen soooo langsamen Rechner, dass Du die Compile-Zeit mit einem Kühlen Blonden überbrücken musst? :lol:

harrybo 31. Jan 2003 19:18

Hi Hansa,

was sein könnte - ohne dass ich Dir Schludrigkeit vorwerfen möchte - der Datentyp von BANKEINZUG ist eventuell doch nicht CHAR(1). Ich schätze, beide Felder sollen Boolean Charakter haben (man hat Bankeinzug oder nicht).

Die Empfehlung zur Repräsentierung dieses Datentyps in Interbase ist ja eine Domain die in etwa so aussieht:
Code:
CREATE DOMAIN DM_BOOL AS SMALLINT DEFAULT 0 CHECK (VALUE BETWEEN 0 AND 1);
Also Integer. Falls der Aufwand vertretbar ist, würde ich die Datenbank entsprechend umbauen.

gruß, harrybo

Hansa 31. Jan 2003 19:20

haha, Compilier-Zeit. Es geht um Datenübernahme. das ist purer Code und pure Daten. Nur ein Memo-Feld, damit man sieht, daß was passiert. Aber es sind ca. 100 MB Daten, die aus Textdatei in die DB rein müssen. Außerdem habe ich einen älteren Rechner für diese Aufgabe vorgesehen und das im Netz. Übernachten will ich aber trotzdem daheim. :mrgreen:

xbu58 31. Jan 2003 19:22

So kannst Du ja auch übernachten :duck:

Hansa 2. Feb 2003 19:15

Ich glaub ich werd noch verrückt. Ich habe die DB jetzt komplett neu aufgebaut, Null-Werte sind immer noch da. Ich hab jetzt einen näher unter die Lupe genommen. Und zwar email eines Lieferanten. Bei Kunden gibt es die auch. Jetzt ist folgender Effekt festzustellen : Der Wert, der mit FindField gesetzt wird, wird nicht angenommen (bei Lieferanten).

Mach ich nun folgendes:

Code:
ALTER TABLE LIEF8 ALTER EMAIL TO LIEFEMAIL
und lasse das Programm, das die Konvertierung macht neu laufen, nachdem ich die Table komplett leer gemacht habe, so funktioniert alles.

Alle Felder behandele ich ungefähr so :

Code:
LiefDS.FindField ('LIEFEMAIL').AsString := copy (zeile,585,30);
Vor der Umbenennung des Feldes sah das ganze eben so aus:

Code:
LiefDS.FindField ('EMAIL').AsString := copy (zeile,585,30);
Wenn ein Feldname in zwei verschiedenen Tabellen benutzt wird, so gibt das doch keinen Fehler, oder doch? Dann dürfte ich aber doch keine ID benutzen, bzw. für jede Tabelle einen anderen Bezeichner. Also ich raffe das nicht mehr.
:cry:

Gruß
Hansa

xbu58 3. Feb 2003 04:14

Hallo Hansa

Zuerst eine Frage:
Liest Du die Daten mit einem Select-Statement aus der Datenbank? Hast Du ev. in diesem Select beide Tabellen als Join drin?
Zum Beispiel so:
Code:
select * from Kunde, Lieferant
Wenn das der Falle ist, dann funktioniert Dein Update oder Insert garantiert nicht mit den gleichen Feldnamen.

Ich nehme aber nicht an, dass eine alter Hase wie Du so einen Fehler macht! :mrgreen:

Für mich sieht das nach einem Fehler im DB-Servers aus. Hatte das vor Jahren (10 Jahre) einmal auf einem Unify-DB-Server auf Unix. Ich habe mir damals angewöhnt, dass die Datenbank-Felder immer mit einem Kürzel der Tabelle versehen sind.
Beispiel:
Code:
Tabelle: Address
Felder: Adr_Num, Adr_Name usw.
Das bringt zudem den Vorteil, dass Du nicht immer mit Substitutes arbeiten musst, wenn Du einen Join benötigst. Wahrscheinlich bringt Dir aber dieser Hinweis nichts, da Dein Programm ja schon steht. Wir mussten damals alle Applikationen anpassen :coder: Hatte uns im Zeitplan um zwei Monate zurück geworfen.

Gruss
Xaver

Hansa 3. Feb 2003 06:46

Zitat:

Zitat von xbu58
Liest Du die Daten mit einem Select-Statement aus der Datenbank?

Daten kommen alle aus einer Textdatei. In jeder Zeile steht ein Datensatz. Die wird nur zerbröselt und dann, wie beschrieben, die einzelnen Felder in die DB eingetragen.

Zitat:

Zitat von xbu58
Für mich sieht das nach einem Fehler im DB-Servers aus.

Kann fast nur so sein. Soweit bin ich auch schon. Deshalb werde ich das ganze jetzt mal mit IB 7 testen. Mit denselben Scripts, dem selben Delphi Programm usw. Wie eine leere DB gefüllt wird, da bin ich ja jetzt fast Spezialist. :mrgreen: Desweiteren werde ich die Frage jetzt auch noch auf englisch übersetzen und sie noch woanders stellen.

Zitat:

Zitat von xbu58
...dass Du nicht immer mit Substitutes arbeiten musst, wenn Du einen Join benötigst....Wir mussten damals alle Applikationen anpassen :coder: Hatte uns im Zeitplan um zwei Monate zurück geworfen.

Meinst Du da sowas wie : "SELECT FROM kunde k, lieferant l..." ? 2 Monate sinds noch nicht, aber im Endeffekt trotzdem mind. eine Woche.

Gruß
Hansa

xbu58 3. Feb 2003 18:08

Hallo Hansa

Hatte mir gedacht, dass Du auch schon an diese Sachen gedacht hast. Mit den Substitutes meine ich genau das was Du geschrieben hast. Das k für Kunde und l für Lieferant ist nicht mehr nötig, wenn z.B. der Kunden-Name Ku_Name und der des Lieferanten Li_Name ist. Wenn man die Tabellen auf die Weise wie ich es beschrieben habe definiert, kannst Du einfach folgendes schreiben:
Code:
SELECT * 
FROM Lieferant
JOIN ArtRel ON Li_Num = ArRe_LiNum
JOIN Art ON ArRe_ArNum = Ar_Num
Ein solches Select wird recht unübersichtlich, wenn Du immer mit Substitutes arbeiten musst.

Aber eben ein bestehende DB umstellen ist halt recht mühsam, auch wenn Delphi da schon einiges komfortabler ist als die C-Umgebung unter Unix und das vor 10 Jahren :roll:

Gruss
Xaver

Hansa 3. Feb 2003 18:37

Hi Xaver,

zuerst einmal folgendes : der Effekt ist heute nicht mehr aufgetaucht. :spin: Heute morgen hatte ich allerdings als allererstes den Rechner komplett neu hochgefahren. Für mich sieht das trotzdem nach Bug aus, aber wo und wann :?: Da ich aber sowieso noch einige andere Tables in oben beschriebener Weise in die DB einfügen muß, kann es wohl nicht lange dauern, bis so was ähnliches passiert, dann bin ich aber vorgewarnt.

Was die, wie heißt das ? Substitutes angeht, frägt es sich, was unübersichtlicher ist. Darauf zu achten, immer andere Bezeichner zu verwenden ? Tja, ob das besser ist ?

Nebenbei bemerkt, die DB existiert hier, sonst nirgends. Die kann ich zumindest im Moment so oft umbauen, neu aufbauen, bis ich sie irgendwann auf die Menschheit loslasse. Na gut einer hat sie schon, der ist aber vorgewarnt, daß er sie wahrscheinlich noch 10mal neu erstellen muß. :mrgreen:

Gruß
Hansa

xbu58 3. Feb 2003 19:01

Hallo Hansa

Na ja, ich kann nur sagen, dass ich damit gute Erfahrungen gemacht habe. Ich habe für mich einige Regel definiert, mit der ich bis heute noch nie angestanden bin. Eine davon ist, dass alles auf english geschrieben ist. Dann verwende ich immer die 2 Anfangsbuchstaben der Tabelle als Bezeichner, ausser es sind abhängige Tabellen.
z.B. Tabelle Documents Bezeichner ist Do_
Abhängige Tabelle DocumentsDet Bezeichner DoD_
Die Forign Key Relation wird in DocumentsDet dann mit DoD_DoCod bezeichnet, wobei Do_Cod in Documents als Primary Key definiert ist.

Ok, ist etwas kompliziert zu erklären, aber sehr einfach in der Anwendung. Auf jeden Fall haben meine Mitarbeiter das Prinzip sehr schnell kapiert 8)

Gruss
Xaver


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