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

So führen Sie ein Python-Skript auf Docker aus

Erstellen Sie zunächst ein spezielles Projektverz...

So mounten Sie die CD, um das RPM-Paket unter Linux zu finden

Vorne geschrieben Manchmal müssen Sie bei der Ver...

Interpretation des Moduls zum Lastenausgleich mit nginx

Inhaltsverzeichnis Zwei Module zur Verwendung von...

So führen Sie das React-Projekt auf dem offiziellen WeChat-Konto aus

Inhaltsverzeichnis 1. Verwenden Sie das „A“-Tag, ...

Tutorial zur Installation und Konfiguration von msmtp und mutt für Raspberry Pi

1. Installieren Sie mutt sudo apt-get install mut...

Vor- und Nachteile von React Hooks

Inhaltsverzeichnis Vorwort Vorteil: Mangel: 1. Re...

CentOS 7 kann nach dem Ändern der Netzwerkkarte nicht auf das Internet zugreifen

Ping www.baidu.com unbekannter Domänenname Ändern...

Einige allgemeine erweiterte SQL-Anweisungen in MySQL

Erweiterte MySQL-SQL-Anweisungen benutze kgc; Tab...

HTML+CSS zur Realisierung einer einfachen Navigationsleistenfunktion

Ohne weitere Umschweife komme ich gleich zum Code...