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

Detaillierte Erläuterung der langsamen MySQL-Protokollabfrage

Langsame Protokollabfragefunktion Die Hauptfunkti...

Beispielcode für die Codevorlage für die Linux C-Protokollausgabe

Vorwort Dieser Artikel stellt hauptsächlich den r...

Detaillierte Erklärung der Javascript-String-Methoden

Inhaltsverzeichnis Zeichenfolgenlänge: Länge char...

Transkript der Implementierung berechneter Vue-Eigenschaften

In diesem Artikel wird das Implementierungszeugni...

So sperren Sie eine virtuelle Konsolensitzung unter Linux

Wenn Sie an einem gemeinsam genutzten System arbe...

Detaillierte Erklärung der Verwendung und Erfahrung mit tinyMCE

Detaillierte Erklärung der tinyMCE-Verwendung Ini...

MariaDB unter Linux startet mit dem Root-Benutzer (empfohlen)

Da ich Sicherheitsprodukte testen musste, wollte ...

Vergessen Sie nicht, den HTML-Tag zu schließen

Das Erstellen von Webseiten, die Webstandards ents...

So deinstallieren Sie IIS7-Web- und FTP-Dienste in Win7 vollständig

Nachdem ich gestern die PHP-Entwicklungsumgebung ...

Detaillierte Erklärung des Parameters slave_exec_mode in MySQL

Heute habe ich zufällig den Parameter slave_exec_...