Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Wo liegt mein Denkfehler ... (https://www.delphipraxis.net/205221-wo-liegt-mein-denkfehler.html)

erich.wanker 13. Aug 2020 11:14

Wo liegt mein Denkfehler ...
 
Hab jetzt endlich meinen Fehler in folgenden Zeilen ausgebessert - mir ist aber nicht ganz klar wieso der ERSTE Versuch NICHT funktioniert:

FAIL if (UniMainModule.d6.FieldByName('archiv').asstring <> '') OR
UniMainModule.d6.FieldByName('archiv').IsNull = false) then begin
Feld_leer:=false;


FUNZT if (UniMainModule.d6.FieldByName('archiv').asstring = '') OR
(UniMainModule.d6.FieldByName('archiv').IsNull) then begin
Feld_leer:=true;


PS.. das mySQL Feld ist ein varchar(40) utf8mb4_general_ci "NULL"

.. hat mir viel Zeit gekostet ;-)

Danke für Hinweise und liebe Grüße
Erich

KodeZwerg 13. Aug 2020 11:22

AW: Wo liegt mein Denkfehler ...
 
//entfernt

erich.wanker 13. Aug 2020 11:28

AW: Wo liegt mein Denkfehler ...
 
ich wollte nur ins Feld "archiv" schreiben, wenn noch nix drinnen steht ..


"wenn was drinnen steht - schreibe ich NICHT" .. funktioniert nicht

"wenn nix drinnen steht - schreibe ich " .. funktioniert

KodeZwerg 13. Aug 2020 11:34

AW: Wo liegt mein Denkfehler ...
 
Ich glaube ich würde es so machen:

schreibe nicht wenn feld belegt ist
Delphi-Quellcode:
if ((UniMainModule.d6.FieldByName('archiv').asstring <> '') AND (NOT UniMainModule.d6.FieldByName('archiv').IsNull)) then

schreibe wenn feld noch frei ist
Delphi-Quellcode:
if ((UniMainModule.d6.FieldByName('archiv').asstring = '') AND UniMainModule.d6.FieldByName('archiv').IsNull) then

Delphi.Narium 13. Aug 2020 11:35

AW: Wo liegt mein Denkfehler ...
 
und was macht dashier?
Delphi-Quellcode:
if (UniMainModule.d6.FieldByName('archiv').asstring <> '') OR (not UniMainModule.d6.FieldByName('archiv').IsNull) then begin ...


Bei der von Dir geposteten Variante für FAIL passt die Klammersetzung nicht? Copy&Paste-Fehler?

Und müsste es dann nicht eher heißen:
Delphi-Quellcode:
if (UniMainModule.d6.FieldByName('archiv').asstring <> '')
and (UniMainModule.d6.FieldByName('archiv').IsNull = false) then begin
Wobei der Vergleich
Delphi-Quellcode:
UniMainModule.d6.FieldByName('archiv').IsNull = false
eher als
Delphi-Quellcode:
not UniMainModule.d6.FieldByName('archiv').IsNull
formuliert werden sollte.

Bei Deiner ersten Variante führt .AsString <> '' dazu, dass alle Sätze, die irgendwas, außer einem Leerstring, enthalten, gefunden werden, .IsNull = false führt zum Finden aller Sätze, die irgendwas enthalten, also auch die mit einem Leerstring. Das Or sorgt dafür, dass beides gefunden wird.

Die zweite Variante liefert alle Sätze, die entweder einen Leersting enthalten oder Null sind.

1. Variante -> nicht Leer oder nicht Null
2. Variante -> Leer oder Null

Irgendwie sind das zwei absolut unterschiedliche Ergebnismengen. Welche davon hättest Du denn gerne?

himitsu 13. Aug 2020 12:25

AW: Wo liegt mein Denkfehler ...
 
Dass man sowas wie
Delphi-Quellcode:
if TheBoolean {Variable/Funktion} = True {Konstante}
niemals machen sollte, sollte langsam mal jeder wissen.
Es wird ja oft genug drauf rumgehackt und der Grund genannt. (siehe tausende Threads hier)

Delphi-Quellcode:
{FAIL} 
//if (FieldByName('archiv').AsString <> '') or (FieldByName('archiv').IsNull = False) then
if (FieldByName('archiv').AsString <> '') or not FieldByName('archiv').IsNull then
if (FieldByName('archiv').AsString <> '') or not (FieldByName('archiv').AsString = '') then // für den Fall NULL das IsNull gegen AsString ersetzt ('' wird durch das erste AsString behandelt)
if (FieldByName('archiv').AsString <> '') or (FieldByName('archiv').AsString <> '') then // ein bissl boolesche Mathematik
if FieldByName('archiv').AsString <> '' then // Gleiches gekürzt
  Feld_leer := False;

{FUNZT} 
if (FieldByName('archiv').AsString = '') or FieldByName('archiv').IsNull then
if FieldByName('archiv').AsString = '' then // IsNull entfernt, weil im AsString enthalten
  Feld_leer := True;

{KURZ}
Feld_leer := FieldByName('archiv').AsString = '';
Grund:
https://www.delphipraxis.net/205186-...ml#post1471558 -> #3 und #4
AsString gibt bei NULL ein '' aus
AsInteger bei NULL ein 0

Was genau ist leer für dich?
Bzw. was erwartest du wann? (NULL, '' oder 'abc')



Ich seh keinen FAIL Fehler, aber kann es zufällig sein, dass dein Compiler irgendwas von nicht-initialisierten Variablen schwafelt und niemand drauf hört?

erich.wanker 13. Aug 2020 13:24

AW: Wo liegt mein Denkfehler ...
 
Hallo Leute.. vielen Dank :-)

"Was genau ist leer für dich?"


Mein Denkfehler: Ich dachte immer - ein Datenbankfeld, das nur erstellt wurde (und noch nie beschrieben wurde) ist "Null" und nicht ''..

Ich war es immer gewohnt bei "Select * from .. WHERE archiv = '' OR archiv IS NULL.." zu schreiben.. ich denke DA gibt es einen Unterschied?

Ich vermute ich mische da 2 Dinge zusammen .. beim SQL-Statement brauch ich dieses "Null" ... beim "FieldByName('archiv').AsString" brauche ich kein "isNull" ..

Ist das korrekt?

LiGrü
Erich

KodeZwerg 13. Aug 2020 13:27

AW: Wo liegt mein Denkfehler ...
 
Das Hauptproblem ist wie Du deine Abfrage stellst. "OR" versus "AND"

"OR" = kann sich auf immens vieles bzw zufälliges beziehen
"AND" = die auswahl wird auf ein minimum reduziert

Uwe Raabe 13. Aug 2020 13:30

AW: Wo liegt mein Denkfehler ...
 
Zitat:

Zitat von erich.wanker (Beitrag 1471772)
ich wollte nur ins Feld "archiv" schreiben, wenn noch nix drinnen steht ..


"wenn was drinnen steht - schreibe ich NICHT" .. funktioniert nicht

"wenn nix drinnen steht - schreibe ich " .. funktioniert

Was genau hat denn nicht funktioniert? Wurde geschrieben wenn es nicht sollte, oder wurde nicht geschrieben wenn es sollte?

erich.wanker 13. Aug 2020 13:44

AW: Wo liegt mein Denkfehler ...
 
Der Fehler war:

Die ersten Zeilen ergaben - das anscheinen etwas im Feld "archiv" steht (obwohl es leer war) - und dadurch nichts (im else begin ..end Block) geschrieben wurde..




****** so funktionierts nicht ******
if (archiv <> '') or (archiv.isnull = false) then
begin
// nicht schreiben
end
else
begin
// schreiben
end;



****** so funktionierts ******
if (archiv = '') or (archiv.isnull) then
begin
// schreiben
end
else
begin
// nicht schreiben
end;

himitsu 13. Aug 2020 13:58

AW: Wo liegt mein Denkfehler ...
 
Stell es dir im Delphi etwa so vor
Delphi-Quellcode:
function TStringField.AsString: string;
begin
  if IsNull then
    Result := ''
  else
    Result := Data;
end;

if field.AsString = '' then
und datenbankseitig wäre es dann ein
SQL-Code:
WHERE coalesce(field, '') = ''

-- oder andersrum
WHERE nullif(field, '') IS NULL





Dein Problem ist also, dass du dich mehr mit Boolescher Algebra beschäftigen solltest.
Wenn du die Operatoren umdrehst, dann ALLE.

Delphi-Quellcode:
if (archiv = '') or archiv.isnull then


ist invertiert
Delphi-Quellcode:
if not ((archiv = '') or archiv.isnull) then
// oder
if (not (archiv = '') and not archiv.isnull) then
// bzw.
if (archiv <> '') and not archiv.isnull then
aber ist nicht
Delphi-Quellcode:
if (archiv <> '') or not archiv.isnull then
//if (archiv <> '') or (archiv.isnull = false) then

Ich kenn auch Leute die drehen es außerhalb um, weil sie es innerhalb nicht können, oder es der Dokumentation/CodeSuche wegen nicht wollen.
Delphi-Quellcode:
if true then
  ...;

if false then
else
  ...;

if not (false) then // wobei man den eigentlichen Code ja nicht umformen muss ... umgeben geht auch
  ...;

erich.wanker 13. Aug 2020 14:19

AW: Wo liegt mein Denkfehler ...
 
"Dein Problem ist also, dass du dich mehr mit Boolescher Algebra beschäftigen solltest"

OOOHHH jaaa.. puhh ... bin ein bisserl planlos wenn ich mir deine Variationen anschaue :oops: ...

ZB: OR -> Ich dachte immer - wenn ich was in klammern setze und eine der Fragestellungen (die in klammern gesetzt wurden) - trifft zu, dann ist das If -THEN erfüllt und es geht los..

und: ich versteh nicht den Unterschied zwischen "not archiv.isnull" und "archiv.isnull = false" .. für mich sind das zwei gleiche Dinge - nur anders geschrieben.

Aber vielen Dank für all die Antworten und Erklärungen :-D

himitsu 13. Aug 2020 14:26

AW: Wo liegt mein Denkfehler ...
 
Es gibt die Konstanten TRUE und FALSE, aber es gibt auch die logischen Auswertungen TRUE und FALSE.

False ist 0
und True ist alles Andere.

Boolean hat 256 Werte (Byte) und LongBool sogar 4 Milliarden (Integer), aber jeweils nur Einer ist FALSE.

Im Delphi ist die True-Konstante = 1 ($01),
aber in WinAPI/C++ ist die Konstante meistent -1 ($FFFFFFFF bzw $FF)

Delphi-Quellcode:
B := True;
if B then OK;
if not B then NEE;
if B = True then OK;
if B = False then NEE;

B := Boolean(2); // Boolean kommt aus einer Funktion und wurde z.B. "berechnet"
if B then OK;
if not B then NEE;
if B = True then OK; // Falsch: if Byte(B) = Byte(True) then ... if 2 = 1 then
if B = False then NEE;
Ist im Prinzip das Gleiche, wie man auch Fließkommazahlen niemals auf Gleichheit prüft.

Delphi.Narium 13. Aug 2020 14:40

AW: Wo liegt mein Denkfehler ...
 
Delphi-Quellcode:
if
(
  (UniMainModule.d6.FieldByName('archiv').AsString = '')
or
  (UniMainModule.d6.FieldByName('archiv').IsNull)
)
then begin
  Feld_leer := true;
und
Delphi-Quellcode:
if not
(
  (UniMainModule.d6.FieldByName('archiv').AsString = '')
or
  (UniMainModule.d6.FieldByName('archiv').IsNull)
)
then begin
  Feld_leer := false;
oder
Delphi-Quellcode:
  Feld_leer := (UniMainModule.d6.FieldByName('archiv').AsString = '')
            or (UniMainModule.d6.FieldByName('archiv').IsNull)
Da himitsu weiter oben bereits erläuterte, dass aus Null in der DB bei .AsString gleich '' wird, kann man das auf
Delphi-Quellcode:
  Feld_leer := (UniMainModule.d6.FieldByName('archiv').AsString = '')

verkürzen.

Uwe Raabe 13. Aug 2020 14:56

AW: Wo liegt mein Denkfehler ...
 
Zitat:

Zitat von erich.wanker (Beitrag 1471770)
FAIL if (UniMainModule.d6.FieldByName('archiv').asstring <> '') OR
UniMainModule.d6.FieldByName('archiv').IsNull = false) then begin
Feld_leer:=false;

Damit dieser Code auch wirklich dazu führt, zu schreiben wenn keine Daten da sind, sollte man vorher
Delphi-Quellcode:
Feld_leer := True
setzen.

himitsu 13. Aug 2020 15:18

AW: Wo liegt mein Denkfehler ...
 
Zitat:

Zitat von himitsu (Beitrag 1471778)
Ich seh keinen FAIL Fehler, aber kann es zufällig sein, dass dein Compiler irgendwas von nicht-initialisierten Variablen schwafelt und niemand drauf hört?

:angle2:


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