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

Wir zeigen Ihnen einen Trick, um einen Textvergleich unter Linux durchzuführen

Vorwort Während des Schreibens des Codes werden w...

Optionsfelder und Multiple-Choice-Schaltflächen werden mit Bildern gestaltet

Ich habe schon Leute fragen hören, wie man Options...

Detailliertes Tutorial zur Offline-Installation von MySQL unter CentOS7

1. Löschen Sie die ursprüngliche MariaDB, sonst k...

Detaillierte Schritte zum Ausführen eines Springboot-Projekts in Linux Docker

Einführung: Die Konfiguration von Docker, auf dem...

Detaillierte Erklärung der CSS-Hintergrund- und Rahmen-Tag-Beispiele

1. CSS-Hintergrund-Tag 1. Stellen Sie die Hinterg...

Installieren Sie Memcached und die PHP Memcached-Erweiterung unter CentOS

In Bezug auf das leistungsstarke verteilte Speich...

Vue implementiert die Shake-Funktion (kompatibel mit ios13.3 und höher)

Vor Kurzem habe ich mit shake.js eine ähnliche Fu...

Detaillierte Schritte zur Installation und Verwendung von VMware ESXi 6.5

Inhaltsverzeichnis Einführung Architektur Vorteil...

Webprojektentwicklung VUE-Mischungs- und Vererbungsprinzip

Inhaltsverzeichnis Mischen Mixin-Hinweis (doppelt...

Methodenbeispiel zum sicheren Abrufen tiefer Objekte von Object in Js

Inhaltsverzeichnis Vorwort Text Parameter Beispie...

MySQL-Performance-Optimierung: So nutzen Sie Indizes effizient und richtig

Die Praxis ist der einzige Weg, die Wahrheit zu t...

So installieren Sie MySQL 5.7.29 mit einem Klick mithilfe eines Shell-Skripts

Dieser Artikel bezieht sich auf die Arbeit des 51...

jQuery implementiert alle Auswahl- und umgekehrten Auswahloperationsfälle

In diesem Artikel wird der spezifische Code von j...