So behandeln Sie einen Überlauf numerischer MySQL-Typen

So behandeln Sie einen Überlauf numerischer MySQL-Typen

Lassen Sie mich Ihnen nun eine Frage stellen. Was passiert, wenn eine Spalte in MySQL auf int(0) gesetzt ist?

Um dieses Problem zu demonstrieren, erstellen wir zunächst eine Tabelle

Tabelle löschen, wenn `na` vorhanden ist;
CREATE TABLE `na` (
n1 INT(0) NICHT NULL STANDARD '0',
n2 INT(11) NICHT NULL STANDARD '0'
);

Dann verwenden wir die folgende Anweisung, um einige Daten in die Tabelle na einzufügen

mysql> INSERT INTO `na` VALUES(520,520),(5201314,5201314);
Abfrage OK, 2 Zeilen betroffen (0,02 Sek.)
Datensätze: 2 Duplikate: 0 Warnungen: 0

Zum Schluss lesen wir es noch einmal durch und sehen

mysql> AUSWÄHLEN * VON na;
+---------+---------+
|
+---------+---------+
| 520 | 520 |
| 5201314 | 5201314 |
+---------+---------+
2 Zeilen im Satz (0,00 Sek.)

Richtig, es scheint, als würde nichts passieren. Es ist richtig, wenn es kein Problem gibt. Ich habe nur Angst, wenn es ein Problem gibt … haha

In diesem Kapitel sprechen wir über Ganzzahlüberlaufprobleme.

Verarbeitung von MySQL-Überläufen numerischer Typen

Wenn MySQL einen Wert in einer numerischen Spalte speichert, der außerhalb des vom Spaltendatentyp zulässigen Bereichs liegt, hängt das Ergebnis vom jeweils aktiven SQL-Modus ab.

  • Wenn der strikte SQL-Modus aktiviert ist, lehnt MySQL Werte, die außerhalb des gültigen Bereichs liegen, gemäß dem SQL-Standard mit einem Fehler ab und das Einfügen schlägt fehl.
  • Wenn kein Einschränkungsmodus aktiviert ist, schneidet MySQL den Wert auf die Ober- und Untergrenze des Spaltendatentypbereichs zu und speichert ihn.
    • Wenn einer Ganzzahlspalte ein außerhalb des Bereichs liegender Wert zugewiesen wird, speichert MySQL den Wert, der den entsprechenden Endpunkt des Bereichs des Spaltendatentyps darstellt.
    • Wenn einer Gleitkomma- oder Festkommaspalte ein Wert zugewiesen wird, der den durch die angegebene (oder standardmäßige) Genauigkeit und Skalierung implizierten Bereich überschreitet, speichert MySQL Werte, die die entsprechenden Endpunkte des Bereichs darstellen.

Das sollte doch leicht zu verstehen sein, oder?

Nehmen wir ein Beispiel und gehen davon aus, dass die Struktur der Tabelle t1 wie folgt ist

Tabelle erstellen t1 (
i1 TINYINT,
i2 TINYINT UNSIGNED
);

Wenn der strikte SQL-Modus aktiviert ist, tritt bei Überschreitung des Bereichs ein Fehler auf.

mysql> SET sql_mode = 'TRADITIONAL'; -- Zuerst den strikten Modus festlegen mysql> INSERT INTO t1 (i1, i2) VALUES(256, 256);
FEHLER 1264 (22003): Wert für Spalte „i1“ in Zeile 1 liegt außerhalb des gültigen Bereichs
mysql> AUSWÄHLEN * VON t1;
Leerer Satz (0,00 Sek.)

Wenn der strikte Modus deaktiviert ist, können Werte eingefügt werden, sie werden jedoch abgeschnitten und es wird eine Warnung ausgegeben.

mysql> SET sql_mode = ''; -- alle Modi deaktivieren mysql> INSERT INTO t1 (i1, i2) VALUES(256, 256);
mysql> WARNUNGEN ANZEIGEN;
+---------+------+------------------------------------------+
| Ebene | Code | Nachricht |
+---------+------+------------------------------------------+
| Warnung | 1264 | Wert für Spalte „i1“ in Zeile 1 liegt außerhalb des gültigen Bereichs |
| Warnung | 1264 | Wert für Spalte „i2“ in Zeile 1 außerhalb des Bereichs |
+---------+------+------------------------------------------+
mysql> AUSWÄHLEN * VON t1;
+------+------+
| ich1 | ich2 |
+------+------+
| 127 | 255 |
+------+------+

Wenn der strikte SQL-Modus nicht aktiviert ist, führen Anweisungen wie ALTER TABLE, LOAD DATA INFILE, UPDATE und mehrzeilige INSERT durch Bereinigung zu Spaltenzuweisungskonvertierungen und geben eine Warnung aus.

Wenn der strikte Modus aktiviert ist, schlagen diese Anweisungen einfach fehl und einige oder alle Werte werden nicht eingefügt oder geändert, abhängig davon, ob es sich bei der Tabelle um eine Transaktionstabelle handelt und von anderen Faktoren.

Ein Überlauf während der Auswertung eines numerischen Ausdrucks führt zu einem Fehler. Da der größte vorzeichenbehaftete BIGINT-Wert beispielsweise 9223372036854775807 ist, führt der folgende Ausdruck zu einem Fehler.

mysql> AUSWÄHLEN 9223372036854775807 + 1;
FEHLER 1690 (22003): BIGINT-Wert liegt außerhalb des Bereichs in '(9223372036854775807 + 1)'

Damit die Operation in diesem Fall erfolgreich ist, muss der Wert in unsigned umgewandelt werden.

mysql> SELECT CAST(9223372036854775807 AS UNSIGNED) + 1;
+----------------------------------------------+
| CAST(9223372036854775807 ALS UNSIGNIERT) + 1 |
+----------------------------------------------+
|9223372036854775808 |
+----------------------------------------------+

Ob ein Überlauf auftritt, hängt andererseits vom Bereich der Operanden ab. Eine andere Möglichkeit zum Verarbeiten des vorherigen Ausdrucks besteht daher darin, die Arithmetik mit exakten Werten zu verwenden, da der Bereich der DECIMAL-Werte größer ist als der der Ganzzahlen.

mysql> AUSWÄHLEN 9223372036854775807.0 + 1;
+-----------------------------+
| 9223372036854775807,0 + 1 |
+-----------------------------+
|9223372036854775808.0 |
+-----------------------------+

Die Subtraktion zwischen ganzzahligen Werten führt standardmäßig zu einem vorzeichenlosen Ergebnis, wenn einer der Typen UNSIGNED ist. Wenn negativ, wird ein Fehler ausgegeben

mysql> SETZE sql_mode = '';
Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)

mysql> SELECT CAST(0 AS UNSIGNED) - 1;
FEHLER 1690 (22003): Der BIGINT UNSIGNED-Wert liegt in „(cast(0 as unsigned) - 1)“ außerhalb des gültigen Bereichs.

In diesem Fall ist das Ergebnis negativ, wenn der SQL-Modus NO_UNSIGNED_SUBTRACTION aktiviert ist.

mysql> SET sql_mode = "NO_UNSIGNED_SUBTRACTION";
mysql> SELECT CAST(0 AS UNSIGNED) - 1;
+-------------------------+
| CAST(0 ALS UNSIGNED) - 1 |
+-------------------------+
| -1 |
+-------------------------+

Wenn das Ergebnis einer solchen Operation zum Aktualisieren einer UNSIGNED-Integer-Spalte verwendet wird, wird das Ergebnis auf den Maximalwert für den Spaltentyp gekürzt oder auf 0, wenn NO_UNSIGNED_SUBTRACTION aktiviert ist. Wenn jedoch der strikte SQL-Modus aktiviert ist, tritt ein Fehler auf und die Spalte bleibt unverändert.

Nachtrag

Alles ist Routine, Routine … im Grunde genommen im Zusammenhang mit dem SQL-Modus …

Zusammenfassen

Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Lernwert für Ihr Studium oder Ihre Arbeit hat. Vielen Dank für Ihre Unterstützung von 123WORDPRESS.COM.

Das könnte Sie auch interessieren:
  • Detaillierte Erklärung häufig verwendeter Datums- und Zeit-/Zahlenfunktionen in MySQL (unbedingt lesen)
  • Lösung für den MySQL-Integer-Datenüberlauf
  • So verwenden Sie MySQL ohne Vorzeichen und lösen das Problem des Komplementüberlaufs beim Subtrahieren
  • So gehen Sie mit dem Speicherüberlaufproblem von MySQL-Ganzzahldaten um

<<:  Node.js+Postman zur Simulation der HTTP-Server- und Client-Interaktion

>>:  Beispielanalyse zum Exportieren, Importieren und Kopieren von Docker-Images

Artikel empfehlen

Mit vsftp einen FTP-Server unter Linux aufbauen (mit Parameterbeschreibung)

einführen In diesem Kapitel wird hauptsächlich de...

JavaScript zur Implementierung des Countdowns für den SMS-Versand

In diesem Artikel wird der spezifische JavaScript...

Bedingtes Rendering von Vue (v-if und v-show)

Inhaltsverzeichnis 1. v-wenn 2. Verwenden Sie v-i...

Detaillierte Erläuterung der Wissenspunkte zu Linux-Dateivorgängen

Verwandte Systemaufrufe für Dateioperationen erst...

Implementierung von Check Constraints in MySQL 8.0

Hallo zusammen, ich bin Tony, ein Lehrer, der nur...

Optimierung der Frontend-Leistung von Websites: JavaScript und CSS

Ich habe einen Artikel des Yahoo-Teams über die O...

HTTP-Rückgabecodeliste (Erklärung auf Chinesisch und Englisch)

Liste der HTTP-Rückgabecodes (unten finden Sie ei...