Mysql: null vs ""


phwert

Erfahrenes Mitglied
#1
Hallo,

vielleicht weiß jemand Rat bzgl. des Nullwert-Problems (s. u.)

Gruß

--------

Code:
select * from mytable;

+----+------+------+
| id | c1   | c2   |
+----+------+------+
|  1 | NULL | X    |
|  2 | A    | y    |
+----+------+------+

Eine Anwendung Anwendung hat die Tabelle aufgerufen. c2 wird geändert. Alle Änderungen sollen gespeichert werden

$v1 = mysqli_real_escape_string($connect, $_POST["v1"]);
$v2 = mysqli_real_escape_string($connect, $_POST["v2"]);

$query = "UPDATE mytable SET ".$_POST["c1"]."= ' ".$v1." ' , ".$_POST["c2"]."= ' ".$v2." '  WHERE id = '".$_POST["id"]."'";

Problem: Mysql interpretiert '' als Wert und nicht als null, d. h. aus dem bisherigen Nullwert c1 wird durch die beiden Hochkommata ('') ein Wert, der zudem auch nicht in der FK-Tabelle enthalten ist.

Wie ist die übliche Vorgehensweise in solchen Fällen?

PS: Ich habe es jetzt so gelöst:

    function checkNullwert($wert) {
    
        if ($wert === "") {
            return ("null");
        } else {
            return ("'" . $wert . "'");
        }
        
    }

$query = "UPDATE mytable SET ".$_POST["c1"]."= ' ".checkNullwert($v1)." ' , ".$_POST["c2"]."= ' ".checkNullwert($v2)." '  WHERE id = '".$_POST["id"]."'";
---------------

drop table mytable;
drop table myfk;

create table myfk (a varchar(1) primary key);
insert into myfk values ("A"),("B");

create table mytable (id int(2)not null auto_increment unique primary key, c1 varchar(1), c2 varchar(1),
constraint fk_myfk foreign key (c1) references myfk (a) on delete cascade on update restrict);

insert into mytable (c2) values ("X");
insert into mytable (c1,c2) values ("A","y");
 
Zuletzt bearbeitet:
#2
Eine Bedingung für Primary Keys ist, dass sie unique sind; das brauchst Du also nicht explizit angeben. Ich habe das eben mal getestet, da ich nicht wusste, ob das nicht sogar einen Fehler produziert, aber kann man tatsächlich auch angeben.

Dann versuche ich beim Tabellen-Layout NULL-Werte zu vermeiden wo immer möglich, da mit NULL-Werten es - zumindest in grauer Vorzeit - immer zu Schwierigkeiten bei den JOINs kam; da muss(te) man höllisch aufpassen.
Da ich auch keine Vorteile in NULL-Werten sehe, gebe ich entsprechende Default-Werte vor, wenn möglich.

Auf dein Beispiel bezogen würde das bedeuten, dass ich beim Zusammenbau der Query nur Nicht-NULL-Werte berücksichtige.

Falls es aber bei dir darauf ankommt, dass eben solche NULL-Werte eingetragen werden müssen, hast Du ja schon eine praktikable Lösung gefunden.
 

Yaslaw

n/a
Moderator
#3
@StormChaser: Null-Werte haben ihre Berechtigung und sollten nicht einfach überschrieben werden.

@phwert: Warum verwendest du nicht die MySQL-Funktionen?

1) Und AUAAAAA! Warum nimmst du c1, c2 und id direkt aus dem Post. Das öfffnet Tür und Tor für Angreiffer!
Mach das weg!

2) "...' ".checkNullwert($v1)." '.." gibt in deinem Fall das folgende zurück: ' 'wert' '
Also zuviele '

Zu deinem Problem. Das kannst du mittels NULLIF() sauber im SQL lösen
SQL:
UPDATE mytable SET feld1= NULLIF($v1, '') WHERE id = $id;
 

phwert

Erfahrenes Mitglied
#4
@StormChaser @Yaslaw
Dass Null ungleich "" ist, kenne ich, wenn ich mich richtig entsinne, von einem anderen großen Datenbankhersteller nicht. Deshalb war ich überrascht, dass ich beim Update auf das Problem wie oben geschildert gestoßen bin.
Nullif(): kannte ich nicht, ist mir der Recherche auch nirgendwo untergekommen.
AUAAAAA: AHHHHHHH!!! Wie mache ich es sonst?
 

Yaslaw

n/a
Moderator
#5
Alle Eingaben mindestens mit input_filter() prüfen.
Die Feldnamen c1 und c2 zusätzlich testen, ob diese Felder auch existieren
Die ID mit mysqli_real_escape_string() parsen.

PS: Welcher andere grosse DB-Hersteller? Ich kenne grad keine ohne NULL.
 
Zuletzt bearbeitet:

Yaslaw

n/a
Moderator
#7
Nein. Ich arbeite mit Oracle. Einer der wichtigsten Befehle ist NVL() um mit NULL vergleichen zu können.
NVL() ist analog zu IFNULL() im MySQL.

Und ja, ich meinte filter_input()



SQL:
select 
    case when null='' then 1 else 0 end                     as empty_string,
    case when null=null then 1 else 0 end                   as null_value,
    case when null='NULL' then 1 else 0 end                 as null_string,
    case when nvl(null, 'NULL')='NULL' then 1 else 0 end    as nvl_string
from dual 

EMPTY_STRING NULL_VALUE NULL_STRING NVL_STRING
------------ ---------- ----------- ----------
           0          0           0          1
 
Zuletzt bearbeitet:

Yaslaw

n/a
Moderator
#9
Nachtrag
Mit '' is null und VARCHAR2 wird '' als NULL interpretiert. Man sollte aber nicht darauf aufbauen, da es bei anderen Vergleichen zu Problemen führen kann.
 

Neue Beiträge