Unterschied zwischen MySQL-Update-Set und und

Unterschied zwischen MySQL-Update-Set und und

Problembeschreibung

Kürzlich erhielt ich eine seltsame Anfrage. Die Update-Anweisung wurde ohne Fehler ausgeführt, die Daten wurden jedoch nicht aktualisiert. Die spezifische problematische Anweisung war ungefähr wie folgt:

Aktualisiere test.stu, setze cname = „0“ und math = 90 und his = 80, wobei id = 100;

Ursachenanalyse

Intuitiv ist die Syntax dieser Update-Anweisung problematisch. Die normale Syntax zum Aktualisieren mehrerer Datenspalten sollte Kommas verwenden, ähnlich der folgenden Form:

Aktualisiere test.stu, setze cname = „0“, math = 90, his = 80, wobei id = 100;

Die erste Reaktion bei der direkten Verwendung von und ist tatsächlich, dass ein Syntaxfehler gemeldet wird, der scheinbar nicht normal ausgeführt werden kann. Anschließend konstruieren wir auf Grundlage der Tencent Cloud-Datenbank MySQL ein einfaches Szenario und versuchen, das Problem zu reproduzieren.

Die SQL-Anweisung lautet wie folgt:

TABELLE ERSTELLEN `stu` (
  `id` int(11) NICHT NULL,
  `sname` varchar(16) NICHT NULL,
  `cname` varchar(8) DEFAULT NULL,
  `math` int(11) NICHT NULL,
  `eng` int(11) DEFAULT NULL,
  `sein` int(11) DEFAULT NULL,
  PRIMÄRSCHLÜSSEL (`id`)
)ENGINE=InnoDB STANDARD-CHARSET=utf8mb4;

in stu-Werte einfügen (100, 'sam', '0', 90,88,83);
in stu-Werte einfügen (101, 'jhon', '1', 97,82,81);
in Stu-Werte einfügen (102, „Mary“, „2“, 87,89,92);
in Stu-Werte einfügen (103, 'Adam', '2', 87,89,92);

Versuchen Sie dann die normale Update-Anweisung und die Update-Anweisung mit und , um die tatsächlichen Ausführungsergebnisse anzuzeigen:

mysql> beginnen;
Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)

mysql> update test.stu setze cname = '0' und math = 90 und his = 80, wobei id = 100;
Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)
Übereinstimmende Zeilen: 1 Geändert: 0 Warnungen: 0

mysql> wähle * von stu;
+-----+-------+-------+------+------+------+------+
| ID | Sname | Cname | Mathe | Eng | Sein |
+-----+-------+-------+------+------+------+------+
| 100 | sam | 0 | 90 | 88 | 83 |
| 101 | jhon | 1 | 97 | 82 | 81 |
| 102 | Maria | 2 | 87 | 89 | 92 |
| 103 | Adam | 2 | 87 | 89 | 92 |
+-----+-------+-------+------+------+------+------+
4 Zeilen im Satz (0,00 Sek.)

mysql> update test.stu setze cname = '0',math = 90,his = 80, wobei id = 100;
Abfrage OK, 1 Zeile betroffen (0,01 Sek.)
Übereinstimmende Zeilen: 1 Geändert: 1 Warnungen: 0

mysql> wähle * von stu;
+-----+-------+-------+------+------+------+------+
| ID | Sname | Cname | Mathe | Eng | Sein |
+-----+-------+-------+------+------+------+------+
| 100 | sam | 0 | 90 | 88 | 80 |
| 101 | jhon | 1 | 97 | 82 | 81 |
| 102 | Maria | 2 | 87 | 89 | 92 |
| 103 | Adam | 2 | 87 | 89 | 92 |
+-----+-------+-------+------+------+------+------+
4 Zeilen im Satz (0,00 Sek.)

mysql> Rollback;
Abfrage OK, 0 Zeilen betroffen (0,01 Sek.)

MySQL>

Sie können sehen, dass keine der Anweisungen einen Fehler meldet und die Update-Anweisung mit den spezifischen Zeilen übereinstimmt (Übereinstimmende Zeilen: 1), die Daten jedoch nicht ändert (Geändert: 0). Die Update-Anweisung mit der Standardsyntax ändert die Daten normal.

Dies zeigt, dass MySQL die Verwendung von und nicht als grammatikalisch falsch ansieht, was bedeutet, dass MySQL diese Anweisung anders „interpretiert“. Am einfachsten ist es, sich zu überlegen, ob MySQL beim Setzen „und“ als logischen Operator interpretiert, statt „und“ im englischen Sinne? Darüber hinaus ist der Wert von cname ursprünglich 0, was mit dem Verhalten der Datenbank bei der Verarbeitung von Bool-Daten übereinstimmt (Verwendung von 0 und 1 anstelle von False und True).

Dies lässt sich ganz einfach überprüfen. Aktualisieren Sie die Daten einfach mit einem anderen CNAME-Wert:

mysql> wähle * von stu;
+-----+-------+-------+------+------+------+------+
| ID | Sname | Cname | Mathe | Eng | Sein |
+-----+-------+-------+------+------+------+------+
| 100 | sam | 0 | 90 | 88 | 83 |
| 101 | jhon | 1 | 97 | 82 | 81 |
| 102 | Maria | 2 | 87 | 89 | 92 |
| 103 | Adam | 2 | 87 | 89 | 92 |
+-----+-------+-------+------+------+------+------+
4 Zeilen im Satz (0,00 Sek.)

mysql> begin;update test.stu setze cname = '0' und math = 90 und his = 80, wobei id = 101;
Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)

Abfrage OK, 1 Zeile betroffen (0,00 Sek.)
Übereinstimmende Zeilen: 1 Geändert: 1 Warnungen: 0

mysql> wähle * von stu;
+-----+-------+-------+------+------+------+------+
| ID | Sname | Cname | Mathe | Eng | Sein |
+-----+-------+-------+------+------+------+------+
| 100 | sam | 0 | 90 | 88 | 83 |
| 101 | jhon | 0 | 97 | 82 | 81 |
| 102 | Maria | 2 | 87 | 89 | 92 |
| 103 | Adam | 2 | 87 | 89 | 92 |
+-----+-------+-------+------+------+------+------+
4 Zeilen im Satz (0,00 Sek.)

mysql> Rollback;
Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)

Aus dem Ergebnis können wir erkennen, dass MySQL den Wert von cname auf 0 ändert, was bedeutet, dass es tatsächlich als logischer Operator behandelt wird. Wenn wir diese Anweisung sorgfältig analysieren, werden wir feststellen, dass MySQL sie wie folgt verarbeitet:

setze cname = ('0' und math = 90 und his = 80)

Die Werte von math und his werden durch die durch die Where-Bedingung gefilterten Zeilen bestimmt. Im obigen Testszenario wird die folgende logische Beurteilung vorgenommen:

'0' und 97 = 90 und 81 = 80

PS: Bitte beachten Sie, dass auch Zeichendaten 0 als Falsch behandelt werden.

Lösung

Derzeit ist es nicht möglich, diese Art von Aktualisierungsanweisung mit „und“ über sql_mode oder andere Parameter zu verhindern, sodass diese Art von Problem relativ verborgen ist. Es wird empfohlen, gekapselte Frameworks zu verwenden oder die Code- bzw. SQL-Überprüfung zu verstärken, um dieses Problem während der Entwicklung zu vermeiden.

PS: Bei Tencent Cloud Database MySQL treten ähnliche Probleme auf, seien Sie also wachsam.

Oben finden Sie detaillierte Informationen zum Unterschied zwischen MySQL-Update-Set und und. Weitere Informationen zu MySQL-Update-Set und und finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM!

Das könnte Sie auch interessieren:
  • Praktisches MySQL + PostgreSQL Batch-Insert-Update insertOrUpdate
  • Nicht standardmäßiger Implementierungscode für die MySQL UPDATE-Anweisung
  • MySQL-Update-Fall Update-Feldwert ist keine feste Operation
  • Zusammenfassung der gemeinsamen Updatemethode für MySQL-Updates mehrerer Tabellen
  • Erläuterung der MySQL-Transaktionsauswahl für die Aktualisierung und Datenkonsistenzverarbeitung
  • Eine "klassische" Falle der MySQL UPDATE-Anweisung

<<:  Eine kleine Sammlung von HTML-Meta-Tags

>>:  Analysieren Sie das Problem der Übertragung von Dateien und anderen Parametern in der Upload-Komponente von Element-UI

Artikel empfehlen

So betreten und verlassen Sie den Docker-Container

1 Starten Sie den Docker-Dienst Zuerst müssen Sie...

Der einfachste Weg, das MySQL-Root-Passwort zurückzusetzen

Meine MySQL-Version ist MySQL V5.7.9, bitte verwe...

Grafisches Tutorial zur Installation und Konfiguration von MySQL 5.7.11 Zip

1. Laden Sie das MySQL 5.7.11 Zip-Installationspa...

Eine kurze Erklärung zum sinnvollen Einsatz von Tabellen und Divs im Seitendesign

Zu Beginn dieses Artikels möchte ich die Fehler in...

Welche Nachteile hat die Bereitstellung der Datenbank in einem Docker-Container?

Vorwort Docker erfreut sich seit zwei Jahren groß...

So lösen Sie das Problem der hohen Parallelität in der MySQL-Datenbank

Vorwort Wir alle wissen, dass Startups zunächst m...

Vue2.0 implementiert adaptive Auflösung

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

So erstellen Sie ein einfaches Säulendiagramm mit Flex-Layout in CSS

Das Folgende ist ein Balkendiagramm im Flex-Layou...

Beispiel für die Bereitstellungsmethode „Forever+nginx“ einer Node-Site

Ich habe vor Kurzem den günstigsten Tencent-Cloud...

Perfekte Lösung für asynchrone Timeout-Vorgänge im JavaScript-Frontend

Inhaltsverzeichnis Was passiert, wenn die Ausführ...

Methoden für JavaScript-String-Objekte

Inhaltsverzeichnis Methoden des String-Objekts Me...

Bereinigungsmethode für das Docker-Verzeichnis /var/lib/docker/aufs/mnt

Der Dienst des Unternehmens verwendet Docker und ...