Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Im Select null oder Wert in WHERE (https://www.delphipraxis.net/203227-im-select-null-oder-wert-where.html)

Kostas 26. Jan 2020 20:45

Datenbank: Firebird • Version: 3.0 • Zugriff über: FIREDAC

Im Select null oder Wert in WHERE
 
Hallo Zusammen,

ich importiere Adressen in einer Tabelle. Jetzt kann es vorkommen dass die Felder Strasse, PLZ und Ort leer sind also wird in der Tabelle NULL geschrieben wird.
Beim importieren kann die erste Adresse keine Strasse haben die zwei keine PLZ die dritte komplett ohne Adresse. Sie darf natürlich nur einmal importiert werden.
Also muss ich jedes Feld dynamisch gegen ein Wert oder gegen Null prüfen. Eine Möglichkeit ist über Macros zu arbeiten.

Code:
SELECT ADRESSID
FROM ADRESSEN
WHERE VORNAME = :VORNAME
  AND NACHNAME = :NACHNAME
  AND STRASSE = :STRASSE
  AND PLZ = :PLZ
  AND ORT = :ORT

Dieses Statement müsse sich jetzt dynamisch z.B.: über Macros ändern z.B.:
SELECT ADRESSID
FROM ADRESSEN
WHERE VORNAME = :VORNAME
  AND NACHNAME = :NACHNAME
!strasseMacro
!plzMacro
!OrtMacro



if quelle.Strasse=''
then MacroByName('strasseMacro').AsRaw = 'AND STRASSE IS NULL'
else MacroByName('strasseMacro').AsRaw = 'AND STRASSE = :STRASSE';
Gibt es keine elegantere Methode?

Gruß Kostas

himitsu 26. Jan 2020 21:34

AW: Im Select null oder Wert in WHERE
 
Was du im Delphi machst, das kann man auch im SQL machen. :zwinker:
z.B. (das IF als IIF, IFTHEN, CASE oder wie auch immer)
SQL-Code:
AND IIF(:STRASSE IS NULL, STRASSE IS NULL, STRASSE = :STRASSE)

bzw. da du ja kein NULL, sondern einen Leerstring in der Variable/Parameter hast
SQL-Code:
AND IIF(:STRASSE = '', STRASSE IS NULL, STRASSE = :STRASSE)

oder sicherheitshalber, falls doch
SQL-Code:
AND IIF(COALESCE(:STRASSE, '') = '', STRASSE IS NULL, STRASSE = :STRASSE)

SQL-Code:
AND IIF(NULLIF(:STRASSE, '') IS NULL, STRASSE IS NULL, STRASSE = :STRASSE)

oder
SQL-Code:
AND ((STRASSE IS NULL AND :STRASSE IS NULL) OR STRASSE = :STRASSE)

SQL-Code:
AND ((STRASSE IS NULL AND NULLIF(:STRASSE, '') IS NULL) OR STRASSE = :STRASSE) -- wieder das wegen '' oder NULL

oder
SQL-Code:
AND COALESCE(STRASSE, :STRASSE) = :STRASSE -- bzw. wegen dem '' oder NULL hier im Delphi als Text oder NULL übergeben

SQL-Code:
AND COALESCE(STRASSE, NULLIF(:STRASSE, '')) IS NOT DISTINCT FROM NULLIF(:STRASSE, '') -- wieder '' oder NULL

SQL-Code:
AND COALESCE(STRASSE, :STRASSE, '') = COALESCE(:STRASSE, '') -- oder andersrum

Kostas 26. Jan 2020 21:53

AW: Im Select null oder Wert in WHERE
 
Hallo himitsu,

ja das ist voll Krank nur weil das SQL damals nicht sauber umgesetzt wurde.
Warum wurde der Vergleich auf NULL anders behandelt als der Vergleich mit einem Wert:
Code:
(AND STRASSE = NULL) (AND STRASSE = 'Bahnhofstasse 1')
Was mich auch ärgert:
Eigentlich müsste das SQL so sein:
Code:
FROM ADRESSEN
SELECT NAME, VORNAME
WHERE NAME = :NAME
C# hat das in LINQ versucht besser zu lösen.

Gruß Kostas

himitsu 26. Jan 2020 21:59

AW: Im Select null oder Wert in WHERE
 
Nja, sauber oder nicht, das ist so eine Sache ... irgendwas mit NULL ergibt halt NULL, außer beim OR.
Und das ist eigentlich in allen Datenbanksprachen einheitlich so.

Drum gibt es ja so Dinge wie COALESCE, CONCAT (statt dem || ), NULLIF, IS DISTINCT FROM, IS NOT DISTINCT FROM usw.

z.B.
SQL-Code:
IS [NOT] DISTINCT FROM
heißt im Postgres so, aber gibt gibt es auch in anderen Sprachen (auch wenn es dort vielleicht anders heißt).
Es vergleicht beide Seiten auf Identisch, und kann auch mit NULL vergleichen, ohne dass dabei NULL raus kommt.

himitsu 26. Jan 2020 22:10

AW: Im Select null oder Wert in WHERE
 
In so manchem DBMS kann man Operatoren auch selbst definieren.
Dort könnteste du dir dann auch einen "kurzen" Operator für Vergleiche mit NULL und EMPTY selbst bauen, wenn/da es sowas oft nicht "vernünftig" gibt,
denn mal ganz im Ernst, aber wer sich
SQL-Code:
IS NOT DISTINCT FROM
ausgedacht hat ... k.A. was der da geraucht hatte.

SQL-Code:
CREATE OR REPLACE FUNCTION compare_with_null(value_a anyelement, value_b anyelement) RETURNS boolean AS $$
  SELECT nullif(value_a, '') = nullif(value_b, '')
  $$ LANGUAGE SQL IMMUTABLE;

CREATE OPERATOR ~= (LEFTARG=anyelement, RIGHTARG=anyelement, PROCEDURE=compare_with_null);


SELECT ADRESSID
FROM ADRESSEN
WHERE VORNAME = :VORNAME
  AND NACHNAME = :NACHNAME
  AND STRASSE ~= :STRASSE
  AND PLZ ~= :PLZ
  AND ORT ~= :ORT

Kostas 26. Jan 2020 22:14

AW: Im Select null oder Wert in WHERE
 
SQL gibt es ja schon sehr lange. Warum bestimmte Sachen nicht verbessert werden ist schon komisch.

In meinen Fall funktioniert das nicht wenn ich auch nach einem NULL prüfen muss :
Code:
AND (STRASSE = :STRASSE)
und ich muss es so schreiben:
Code:
AND ((STRASSE IS NULL AND :STRASSE IS NULL) OR (STRASSE = :STRASSE))

Kostas 26. Jan 2020 22:16

AW: Im Select null oder Wert in WHERE
 
Zitat:

Zitat von himitsu (Beitrag 1456031)
...
SQL-Code:
IS NOT DISTINCT FROM
ausgedacht hat ... k.A. was der da geraucht hatte.

:lol:

ja, da gibt es einiges. :lol: so bleibt es nicht langweilig.

himitsu 26. Jan 2020 22:23

AW: Im Select null oder Wert in WHERE
 
Zitat:

Zitat von Kostas (Beitrag 1456032)
In meinen Fall funktioniert das nicht wenn ich auch nach einem NULL prüfen muss

Jupp, drum die COALESCE bzw. NULLIF, um das NULL mit zu behandeln,
z.B. siehe die Varianten nach dem letzten "oder". :zwinker:
Das Erste davon mit NULL im Delphi abgefangen und das Letzte davon im SQL behandelt.
Delphi-Quellcode:
// im Delphi
if quelle.Strasse=''
then ParamByName('strasse').Clear //ParamByName('strasse').AsValue = Null
else ParamByName('strasse').AsString = quelle.Strasse;

p80286 26. Jan 2020 23:38

AW: Im Select null oder Wert in WHERE
 
Es ist schon ungewöhnlich, wenn ein Textfeld wie "Strasse" mit NULL initialisiert wird, da Wert nicht vorhanden recht gut mit einem Leerstring widergegeben werden kann. Anders ist es bei numerischen oder Datumswerten da wird ein NULL hierfür benötigt.

Gruß
K-H

mkinzler 27. Jan 2020 08:10

AW: Im Select null oder Wert in WHERE
 
Zitat:

ja das ist voll Krank nur weil das SQL damals nicht sauber umgesetzt wurde.
Warum wurde der Vergleich auf NULL anders behandelt als der Vergleich mit einem Wert
Weil NULL kein Wert ist.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:43 Uhr.
Seite 1 von 2  1 2      

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