Eine detaillierte Analyse des Mordes, der durch ein falsch platziertes Anführungszeichen in MySQL verursacht wurde

Eine detaillierte Analyse des Mordes, der durch ein falsch platziertes Anführungszeichen in MySQL verursacht wurde

1. Einleitung

In letzter Zeit erlebe ich es oft, dass Entwickler versehentlich Daten löschen oder aktualisieren. Jetzt haben sie mir wieder Probleme bereitet. Sehen wir uns den gesamten Vorgang einmal an.

2. Prozess

Da die Entwicklung in der Produktionsphase Daten reparieren muss, müssen 120 SQL-Anweisungen ausgeführt und die Daten aktualisiert werden

Der Entwickler stellte also eine Verbindung zur Produktionsdatenbank her und führte die erste SQL

Tabellennamen aktualisieren Quellname festlegen = "bj1062-Beichen Fudi, Changying, Bezirk Chaoyang, Peking"
wobei Quellname = "-Beichen Fudi, Changying, Bezirk Chaoyang, Peking"

Wir haben uns dieses SQL genauer angesehen und festgestellt, dass es tatsächlich kein Problem gibt. Die Where-Bedingung ist auch normal. Die allgemeine Idee besteht darin, die Zeichenfolge bj1062 vor der Adresse hinzuzufügen. Liegt wirklich kein Fehler vor? Ja, es liegt kein Fehler vor. Nach Abschluss der Entwicklung entsprachen die Ergebnisse tatsächlich den Erwartungen.

Anschließend hat der Entwickler den Rest des SQL ausgeführt, der mit dem obigen SQL identisch ist, um die Adresse zu aktualisieren. Nachdem die Ausführung abgeschlossen war, war der Entwickler verwirrt und stellte fest, dass source_name 0 geworden war. Der Entwickler rief mich schnell an und sagte:

Harvey, ich habe das Update ausgeführt, die Where-Bedingungen sind korrekt und die eingestellten Werte sind auch korrekt, aber alle Felder nach dem Einstellen sind zu 0 geworden. Können Sie mir helfen, zu überprüfen, ob die Daten wiederhergestellt werden können?

Ich habe mich schnell beim Server angemeldet und während dieser Zeit das Binlog überprüft. Ich habe eine große Anzahl von Anweisungen vom update tablename set source_name=0 gefunden. Ich habe binlog2sql verwendet, um sie zu analysieren. Projektadresse: binlog2sql

Wir haben zusammen mit dem Entwickler schnell den Zeitpunkt des Einsatzes ermittelt, das Flashback-SQL generiert, die Daten wiederhergestellt und die Beweise vor Ort gesichert.

Dann habe ich das von der Entwicklung ausgeführte SQL überprüft und mehrere sehr merkwürdige SQLs gefunden:

Die Anführungszeichen in diesen SQL-Anweisungen werden nach dem Where-Feldnamen platziert. Die vereinfachte SQL-Anweisung lautet:

Aktualisiere Tabellenname und setze str_col="xxx" = "yyy"

Wie führt dieses SQL also eine semantische Konvertierung in MySQL durch?

Könnte es so etwas sein?

Aktualisiere tbl_name set (str_col="xxx" ) = "yyy"

Dies ist ein Grammatikfehler und tritt nur in der folgenden Form auf:

Aktualisiere Tbl_Name und setze str_col=("xxx" = "yyy")

Und

wähle "xxx" = "yyy"

Der Wert von ist 0, also

Aktualisiere Tabellenname und setze str_col="xxx" = "yyy"

Äquivalent zu

Aktualisiere Tbl_Name und setze str_col=0

Daher werden alle source_name-Felder auf 0 aktualisiert.

Lassen Sie uns untersuchen, was mit dieser Art von Aussage in ausgewählter Form passiert.

mysql [localhost] {msandbox} (Test) > wähle ID, str_col aus tbl_name, wobei str_col="xxx" = "yyy";
+----+---------+
| Ich würde | str_col |
| 1 | aaa |
+----+---------+ | 2 | aaa |
+----+---------+
| 3 | aaa |
| 4 | aaa |

Wir haben festgestellt, dass dieses SQL auch die Datensätze mit str_col='aaa' gefunden hat. Warum?

mysql [localhost] {msandbox} (Test) > Warnungen
Warnungen anzeigen aktiviert.
mysql [localhost] {msandbox} (Test) > erweitertes Select ID,str_col from tbl_name erklären, wobei str_col="xxx" = "yyy"\G
*************************** 1. Reihe ***************************
ID: 1 Auswahltyp: SIMPLE Tabelle: tbl_name Typ: Index
1 Zeile im Satz, 1 Warnung (0,00 Sek.)
mögliche Schlüssel: NULL
Schlüssel: idx_str
Ref: NULL
key_len: 33 Zeilen: 4
Extra: Verwenden von „where“; Verwenden von „index“
gefiltert: 100,00
Hinweis (Code 1003): /* select#1 */ select `test`.`tbl_name`.`id` AS `id`,`test`.`tbl_name`.`str_col` AS `str_col` from `test`.`tbl_name` where ((`test`.`tbl_name`.`str_col` = 'xxx') = 'yyy')

Hier transformiert er die Where-Bedingung in

((`test`.`tbl_name`.`str_col` = 'xxx') = 'yyy')

Diese Bedingung ermittelt zunächst, ob str_col und 'xxx' gleich sind. Wenn sie gleich sind, ist der Wert in den Klammern 1. Wenn sie nicht gleich sind, ist er 0.
Anschließend wird 0 oder 1 mit ‚yyy‘ verglichen.

Da eine Seite des Gleichheitszeichens eine Ganzzahl und die andere Seite eine Zeichenfolge ist, werden beide Seiten zum Vergleich in Gleitkommazahlen konvertiert.

Fallanalyse von Abfrageergebnisfehlern, die durch implizite Konvertierung in MySQL verursacht werden

„yyy“ wird in einen Gleitkommatyp konvertiert und ist gleich 0. 0 ist im Vergleich mit 0 immer gleich 1.

mysql [localhost] {msandbox} (Test) > wähle 'yyy'+0,0;
+-------------+
| 'yyy'+0,0 |
| 0 |
+-------------+
mysql [localhost] {msandbox} (Test) > Auswahl 0=0;
+-------------+
1 Zeile im Satz, 1 Warnung (0,00 Sek.)
+-----+
1 Zeile im Satz (0,00 Sek.)
| 0=0 |
+-----+
+-----+
| 1 |

Dies führt dazu, dass das Ergebnis immer wahr ist, d. h. die Select-Anweisung entspricht dem folgenden SQL

Wählen Sie ID, str_col aus tbl_name, wobei 1=1;

Es werden sämtliche Datensätze abgefragt.

3. Zusammenfassung

Beim Schreiben von SQL müssen Sie darauf achten, dass die Anführungszeichen an der richtigen Stelle stehen. Wenn die Anführungszeichen an der falschen Stelle stehen, ist das SQL manchmal immer noch normal, aber es führt dazu, dass alle Ausführungsergebnisse falsch sind. Vor der Ausführung müssen Sie den Test in der Testumgebung ausführen und die Syntaxhervorhebung der IDE verwenden, um entsprechende Probleme zu identifizieren.

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. Wenn Sie Fragen haben, können Sie eine Nachricht hinterlassen. Vielen Dank für Ihre Unterstützung von 123WORDPRESS.COM.

Das könnte Sie auch interessieren:
  • Umgang mit einfachen und doppelten Anführungszeichen in SQL-Anweisungen
  • Erklärung der einfachen und doppelten Anführungszeichen in PostgreSQL
  • Mybatis fügt der generierten SQL-Anweisung automatisch einfache Anführungszeichen hinzu
  • Ausführliche Erklärung zum Fehler beim Schreiben eines einfachen Anführungszeichens "''''" in SQL
  • So verwenden Sie einfache und doppelte Anführungszeichen in SQL-Anweisungen

<<:  CentOS 8 ist jetzt verfügbar

>>:  Natives JS zur Realisierung eines einfachen Schlangenspiels

Artikel empfehlen

Detaillierte Einführung in den DOCTYPE-Typ

<br />Wir deklarieren DOCTYPE in HTML normal...

CSS horizontale Zentrierung und Begrenzung der maximalen Breite

Eine CSS-Layout- und Stilfrage: Wie kann man die ...

Detaillierte Schritte zum Speichern von Emoji-Ausdrücken in MySQL

Verursacht durch: java.sql.SQLException: Falscher...

Beispiel für die Erschöpfung der MySQL-Auto-Increment-ID

Anzeigedefinitions-ID Wenn die in der Tabelle def...

So lösen Sie das Problem, das Root-Passwort von Mysql auf dem Mac zu vergessen

Ich habe MySQL auf meinem Computer längere Zeit n...

Implementierung der Validierung mehrerer Elemente im Formular

Im Projekt werden häufig Formulartests durchgefüh...

MySQL-Reihe von Erfahrungszusammenfassungen und Analyse-Tutorials zu NULL-Werten

Inhaltsverzeichnis 1. Testdaten 2. Die Unannehmli...

Detaillierte Analyse von MySQL-Datenbanktransaktionen und -Sperren

Inhaltsverzeichnis 1. Grundlegende Konzepte SÄURE...

Einführung in integrierte JavaScript-Objekte

Inhaltsverzeichnis 1. Eingebaute Objekte 2. Mathe...