Frage

Ich benutzen den Standard mysql_connect () zu verwenden, mysql_query (), etc Aussagen zu tun MySQL Sachen von PHP. In letzter Zeit habe ich worden mit der wunderbar MDB2 Klasse Umschaltung. Zusammen mit ihm bin ich mit Prepared Statements, so dass ich keine Angst habe, um meine Eingabe und SQL-Injection-Attacken zu entkommen.

Allerdings gibt es ein Problem in ich laufe. Ich habe eine Tabelle mit einigen VARCHAR-Spalten, die als nicht-null angegeben werden (das heißt, nicht zulassen, dass NULL-Werte). Mit den alten MySQL PHP-Befehle, ich könnte so tun Dinge ohne Probleme:

INSERT INTO mytable SET somevarchar = '';

Nun aber wenn ich eine Abfrage wie:

INSERT INTO mytable SET somevarchar = ?;

Und dann in PHP Ich habe:

$value = "";
$prepared = $db->prepare($query, array('text'));
$result = $prepared->execute($value);

Damit wird der Fehler "null value violates not-null constraint"

werfen

als eine vorübergehende Lösung, überprüfe ich, ob $value leer ist, und es (ein Leerzeichen) " " ändern, aber das ist eine schreckliche Hack und könnte andere Probleme verursachen.

Wie soll ich leere Strings mit vorbereiteten Anweisungen einzufügen, ohne eine NULL stattdessen einfügen wollen?

EDIT: Es ist zu groß ein Projekt durch meine gesamte Code-Basis zu gehen, findet überall die eine leere Zeichenfolge „“ verwendet und es ändert NULL stattdessen zu verwenden. Was muss ich wissen, ist, warum Standard-MySQL-Abfragen behandeln „“ und NULL als zwei getrennte Dinge (wie ich glaube, richtig ist), aber vorbereitete Anweisungen konvertiert „“ in NULL.

Beachten Sie, dass "" und NULL sind nicht die gleiche Sache. Zum Beispiel SELECT NULL = ""; NULL kehrt statt 1 wie man erwarten würde.

War es hilfreich?

Lösung

Das klingt wie ein Problem mit dem MDB2 API PHP Duck Typing Semantik Fummelei. Da die leere Zeichenfolge in PHP entspricht NULL ist, MDB2 ist wahrscheinlich falsch behandeln sie als solche. Die ideale Lösung wäre eine Lösung für sie zu finden in ihm API, aber ich bin nicht allzu vertraut.

Eine Sache, die Sie sollten allerdings bedenken, ist, dass eine leere Zeichenfolge in SQL ist kein NULL-Wert. Sie können sie in Zeilen einfügen deklariert ‚NOT NULL‘ ganz gut:

mysql> CREATE TABLE tbl( row CHAR(128) NOT NULL );
Query OK, 0 rows affected (0.05 sec)

mysql> INSERT INTO tbl VALUES( 'not empty' ), ( '' );
Query OK, 2 rows affected (0.02 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> SELECT row, row IS NULL FROM tbl;
+-----------+-------------+
| row       | row IS NULL |
+-----------+-------------+
| not empty |           0 | 
|           |           0 | 
+-----------+-------------+
2 rows in set (0.00 sec)

mysql> INSERT INTO tbl VALUES( NULL );
ERROR 1048 (23000): Column 'row' cannot be null

Wenn Sie nicht in der Lage sind zu finden (oder implementieren) eine Abhilfe in dem MDB2 API, eine hackish Lösung (wenn auch etwas besser als die gerade verwendet wird) könnte ein Benutzervariable für den leeren String -

SET @EMPTY_STRING = "";
UPDATE tbl SET row=@EMPTY_STRING;

Schließlich, wenn Sie die leere Zeichenkette in einer INSERT-Anweisung verwenden, müssen aber selbst nicht in der Lage zu sein, der Standardwert für String-Typen in MySQL zu finden, ist eine leere Zeichenfolge. Also könnte man einfach die Spalte von INSERT-Anweisung weglassen und es würde automatisch auf die leere Zeichenfolge gesetzt bekommen (vorausgesetzt, die Spalte eine NOT NULL Bedingung hat).

Andere Tipps

Durch einige der Antworten, wurde mir klar, dass das Problem in der MDB2 API sein kann und nicht in der PHP oder MySQL-Befehle selbst. Sicher genug, fand ich dies in der MDB2 FAQ:

  
      
  • Warum leere Zeichenfolge als NULL in der Datenbank landen? Warum erhalte ich eine NULL   nicht in NOT NULL Textfelder erlaubt   obwohl der Standardwert ist „“?      
        
    • Das Problem ist, dass für einige RDBMS (die meisten vornemlich Oracle) ein leeres   String ist NULL. daher MDB2   bietet eine Portabilität Option   erzwingen das gleiche Verhalten auf allen   RDBMS.
    •   
    • Da alle Portabilität Optionen standardmäßig aktiviert sind, werden Sie   die Funktion zu deaktivieren, wenn Sie nicht   wollen, dieses Verhalten haben:   $ Mdb2-> setOption ( 'Portabilität',   MDB2_PORTABILITY_ALL ^   MDB2_PORTABILITY_EMPTY_TO_NULL);
    •   
  •   

Danke an alle, die nachdenklichen Antworten zur Verfügung gestellt.

Ich weiß, diese Frage ist so ziemlich beantwortet und im Ruhestand, aber ich fand es während für Antworten auf eine ähnliche Situation suchen, und ich kann meinen Hut werfen im Ring nicht widerstehen.

Ohne zu wissen, was die NULL / „“ Spalte bezieht sich auf, kann ich nicht wissen, wie die wahre Bedeutung eines leeren String. Ist leere Zeichenkette bedeutet etwas für sich (wie, wenn ich einen Richter überzeugen lassen Sie mich meinen Namen nichts zu einfach ändern, würde ich wirklich irritiert sein, wenn mein Name auf meinem Führerschein als NULL auftauchten. Mein Name wäre!

Allerdings ist die leere Zeichenfolge (oder leer, oder das Nichts, das etwas, nicht nur der Mangel an etwas (wie NULL) ist) auch „NOT NULL“ oder „Nichts, aber immer noch nicht Null“ bedeutet einfach nur kann. Man könnte sogar in die andere Richtung gehen und deuten darauf hin, dass das Fehlen des Wertes NULL macht es noch etwas weniger als Null, Cuz mindestens Null einen Namen hat, können Sie laut sagen!

Mein Punkt ist, dass, wenn die leere Zeichenkette eine direkte Darstellung einiger Daten (wie ein Name, oder das, was ziehe ich zwischen den Zahlen in meiner Telefonnummer, usw. eingefügt werden), dann Ihre Optionen sind entweder bis zu argumentieren ‚re wund für die rechtmäßige Verwendung von leeren String oder etwas zu verwenden, die eine leere Zeichenfolge darstellt, die nicht NULL ist (wie ein ASCII-Steuerzeichen oder eine Unicode-Äquivalent, einem regex Wert irgendeiner Art, oder, noch schlimmer, eine beliebige noch völlig ungenutzt Token, wie: ◘

Wenn die leere Zelle wirklich nur NOT NULL bedeutet, dann könnte man von einer anderen Art und Weise denkt, es auszudrücken. Eine dumme und offensichtliche Art und Weise ist der Ausdruck „Nicht NULL“. Aber ich habe das Gefühl, dass NULL bedeutet soviel wie „nicht Teil dieser Gruppe überhaupt“, während die leere Zeichenkette bedeutet soviel wie „dieser Typ ist cool, er hat einfach nicht seine Bande Tattoos bekommt noch“. In diesem Fall würde ich mit einem Begriff / Namen / Idee für diese Situation, wie „default“ oder „Anfänger“ oder „Pending“ kommen.

Wenn nun durch einige verrückte Chance tatsächlich Sie leere Zeichenfolge möchten, dass darzustellen, die nicht einmal würdig NULL ist, wieder, kommen mit einem signifikanteren Symbol dafür, wie „-1“ oder „SUPERNULL“ oder " uglies“.

Im indischen Kastensystem, sind die niedrigsten Caste Shudra: Bauern und Arbeiter. Unterhalb dieser Kaste sind die Dalit: "The Untouchables". Sie sind nicht eine niedrigere Kaste betrachtet, weil sie als die niedrigste Kaste Einstellung einer Kontamination des gesamten Systems betrachtet werden würde.

Also Sie mich nicht für verrückt für leere Strings denken kann als NULL schlechter sein!

"Bis zum nächsten Mal.

Ich fand die Lösung!

MDB2 wandelt leere Zeichenfolgen auf NULL, weil Portabilität Option MDB2_PORTABILITY_EMPTY_TO_NULL standardmäßig aktiviert ist (dank Oracle, die leere Zeichenfolgen betrachtet werden null).

Schalten Sie diese Optionen aus, wenn Sie eine Verbindung zur Datenbank:

$options = array(
    'portability' => MDB2_PORTABILITY_ALL ^ MDB2_PORTABILITY_EMPTY_TO_NULL
);
$res= & MDB2::connect("mysql://user:password@server/dbase", $options);

Während 0 und leere Strings sind Variablen NULL ist das Fehlen von Daten. Und glauben Sie mir, es ist viel einfacher, eine Abfrage

zu schreiben

SELECT * from table where mything IS NULL als zu versuchen, für leere Strings abfragen: /

Ist kein leerer Satz zitiert, "" das tun?

Ich bin verwirrt. Es sieht aus wie Sie mysqli OO verwenden (von den Tags und Stil), aber die Syntax ist anders als das Handbuch auf php.net, die dies zu tun, statt sagt:

$query = "INSERT INTO mytable SET somevarchar = ?";
$value = "";
$prepared = $db->prepare($query);
$prepared->bind_param("s", $value);
$result = $prepared->execute();
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top