Anführungzeichen in SQL command

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
Ernie1412
User
Beiträge: 161
Registriert: Freitag 10. Januar 2020, 20:38

wie kriege ich " Zeichen im SQL command, wenn ein value ein ' enthält ?

Code: Alles auswählen

command="""INSERT INTO Scrap_ArtistInfos (ArtistID,low,SettingID,logo,DateiOrdner,Beschreibung) VALUES (NULL,%s,%i,%s,%s,"%s");""" % (low,setting_id,logo,DateiOrdner,Beschreibung,)
ich habs mit f"INSERT ... versucht
ich habs mit "INSERT ....format(...) versucht


wenn ich das wie oben mache, bekomme ich als Ergebnis:

Code: Alles auswählen

'INSERT INTO Scrap_ArtistInfos (ArtistID,low,SettingID,logo,DateiOrdner,Beschreibung) VALUES (NULL,startrek,1,background-image: url(:/Logos/grafics/StarTrek/startrek_90x40.png),Y:\\_Label\\StarTrek,"//div[@class=\'xz1bz0-0 bNiqBh\']/p");'
der macht vor dem ' Zeichen ein \ davor. ... class=\'xz1bz0-0 bNiqBh\']/p...
Beschreibung="//div[@class='xz1bz0-0 bNiqBh']/p"

Keine Ahnung warum, wieso ;(
Welche Möglichkeiten gibts denn noch, um beides " und ' zu adden ?
Benutzeravatar
sparrow
User
Beiträge: 4577
Registriert: Freitag 17. April 2009, 10:28

Man baut keine Values per Stringformatierung in ein SQL-Statement. Niemals. Das ist nicht nur in diesem Fall ärgerlich, das ist vor allem ein riesiges Sicherheitsproblem. Wenn du Usereingaben in SQL-Statements zulässt, steht dem Benutzer damit die Datenbank offen. Stichwort: SQL Injektion.

Erster Anlautpunkt, sollte immer die Dokumentation sein. Und wenn du dir die anschaust, findest du auch, wie man Values in sqlite3 Statements verwendet.

Code: Alles auswählen

statement = "INSERT INTO Scrap_ArtistInfos (ArtistID,low,SettingID,logo,DateiOrdner,Beschreibung) VALUES (?, ?, ?, ?, ?, ?);"
cursor.execute(statement, (None, low, setting_id, logo, datei_ordner, beschreibung))
Ich war so frei und habe gleich die falsch geschrieben Namen angepasst. Namen werden in Python klein_mit_unterstrich geschrieben. Außer Klassen (PascalCase) und Konstanten (KOMPLETT_GROSS).

Bitte verwende SQL Statements immer so. Und ein Blick in die Dokumentation ist zumindest nie hinderlich.
Benutzeravatar
__blackjack__
User
Beiträge: 14185
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Ich würde das mit den Namen auch noch auf die Namen in der Datenbank erweitern, denn SQL unterscheidet nicht zwischen Gross- und Kleinschreibung, und Datenbanken dürfen dementsprechend Namen auch normalisieren und beispielsweise `ArtistID` als `ARTISTID` oder `artistid` anzeigen. Und da ist `ARTIST_ID` oder `artist_id` leichter lesbar, weil man nicht im Kopf anfangen muss die Wortgrenze(n) zu finden.
“Every thinking person fears nuclear war and every technological nation plans for it. Everyone knows
it's madness, and every country has an excuse.” — Carl Sagan, Cosmos, Episode 13: Who Speaks for Earth?
Ernie1412
User
Beiträge: 161
Registriert: Freitag 10. Januar 2020, 20:38

ich benutze QtSQL und SQLite
habs nun mit query.bindValue() hinbekommen.
Benutzeravatar
DeaD_EyE
User
Beiträge: 1275
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Genau aus solchen Gründen sind Template-Strings eingeführt worden. Der Syntax ist gleich wie bei den f-strings, aber der Unterschied ist, dass man Template-Strings zuvor interpolieren muss. Eine Funktion, die dann z.B. speziell fürs Escapen zuständig ist, übernimmt dann diese Aufgabe. Am Ende wird ein normaler str ausgegeben.

Ist noch ziemlich neu und wahrscheinlich gibt es bis jetzt noch nicht viele Bibliotheken, die das unterstützen.
Cool wäre es z.B. wenn sqlite3 eine Funktion für Template-Strings bereit stellt.

Bis jetzt würde ich aber den klassischen Weg gehen und SQL-Statement getrennt von Daten behandeln. Deswegen kann man execute 2 Argumente übergeben. Das erste Artgument ist das SQL-Statement ohne Daten und das zweite Argument sind die Daten. Das zweite Argument, also die Daten, werden automatisch Escaped. Das ist also sicher.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
oldboyJR
User
Beiträge: 69
Registriert: Donnerstag 28. März 2024, 16:19

$sql = "INSERT INTO petitionmg (Anrede, Vorname, Nachname, Email, Strasse, Nummer, Ort, PLZ, Bundesland, Kommentare, Unterstuetzer )
VALUES ('" .$Anrede ."', '" .$Vorname ."','" .$Nachname ."', '" .$Email ."', '" .$Strasse ."','" .$Nummer ."', '" .$Ort ."', '" .$PLZ ."', '" .$Bundesland ."', '" .$Kommentare ."', '" .$Unterstuetzer ."' )";
Benutzeravatar
sparrow
User
Beiträge: 4577
Registriert: Freitag 17. April 2009, 10:28

@oldboyJR: Was genau ist der Sinn, dass du hier alte Threads ausgräbst und mit fragwürdigen Posts ergänzt? Oder wo ist hier der Bezug zu Windows?
Benutzeravatar
__blackjack__
User
Beiträge: 14185
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@oldboyJR: Das ist keine Python-Syntax und man bastelt in keiner Sprache SQL-Anweisungen als Zeichenkette mit Werten zusammen, wenn man nicht möchte dass da SQL-Injection passieren kann.
“Every thinking person fears nuclear war and every technological nation plans for it. Everyone knows
it's madness, and every country has an excuse.” — Carl Sagan, Cosmos, Episode 13: Who Speaks for Earth?
oldboyJR
User
Beiträge: 69
Registriert: Donnerstag 28. März 2024, 16:19

Sorry ist das nicht Systemunabhängig? Mysql ist doch eine opensoftware Server lösung die sowohl in einem Internen server wie xampp als auch unter externen Server installiert werden kann und ein und die selbe Sequenz braucht? Sonst würde doch die systenübergreifende Eigenschaften fehlen. Ist es nicht erforderlich das in dem Programm die SQL-Injection durch überprüfungen ausgeschlossen werden oder ist das eine naive und unnötige Einstellung? Natürlich habe ich nicht daran gedacht das unterschiedliche Treiber andere Sequenzen brauchen oder? Ist ein neues System nicht mit einer neuen ID verbunden die dann ein falschen Hasch erzeugt? Sowie ein anderer Browser, Benutzernummer auch eine Fehlermeldung erzeugt wenn man die selbe Bank aufruft? Also muß man dann doch noch fragen welchen Treiber in welcher Version usw. ? Bevor wir alle spekulieren was falsch ist. Unter PHP und Java sind die Anforderungen die selben! Erfolglose Sequenzen sind abhängig vom Treiber und Versionsnummer sowie es Probleme gibt, wenn man eine neue Python Version nimmt, bei denen die Module auf den neusten Stand gebracht hat und sich Syntax verändern.
Benutzeravatar
sparrow
User
Beiträge: 4577
Registriert: Freitag 17. April 2009, 10:28

@oldboyJR: WIr brauchen überhaupt nicht spekulieren, weil das, was du hier zeigst, falsch ist. Egal in welcher Sprache. Das was du schreibst wirkt für mich alles sehr wirr und gar nicht passend.

Zur Klarstellung: SQL ist ein Standard, der definiert ist und den verschiedene Datenbanken unterschiedlich genau umsetzen.
In der Regel schickt man aber kein rohes SQL an die Datenbank. Eben um zum Beispiel SQL-Injections zu verhindern. In Python können die verwendeten Platzhalter unterschiedlich sein, deshalb sollte man in die Dokumentation schauen.
Wenn man da eine Abstraktion möchte, hilft unter Python der Einsatz von SQLAlchemy.

Zu deinem kaputten Beispiel weiter oben, das einfach ein SQL-Statement zusammenbaut: Keine Ahnung aus welcher Programmiersprache du das gefummelt hast, aber auch dort sollte man sicher nicht Statments einfach zusammensetzen. Wir nehmen an, dass wir mit einer MariaDB sprechen und schauen deshalb in die Dokumentation, orientieren uns daran und schreiben dann das Statement richtig:

Code: Alles auswählen

sql = (
	"INSERT INTO petitionmg "
	"(Anrede, Vorname, Nachname, Email, Strasse, Nummer, Ort, PLZ, Bundesland, Kommentare, Unterstuetzer) "
	"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
)
cur.execute(
     sql,
    (anrede, vorname, nachname, email, strasse, nummer, ort, plz, bundesland, kommentare, unterstuetzer)
)
Das steht auch alles schon in diesem Thread. Zumindest ich verstehe nicht, warum du dann etwas, das mit Python so gar nichts zu tun hat, hinzugefügt hast.

Ich vermute auch, dass du die Relationen in der Datenbank falsch umgesetzt hast und es keine Normalisierung gibt. Die Namen "Kommentare" und "Unterstuetzer" sind in Mehrzahl, was darauf hindeutet, dass es mehrere davon für einen Eintrag gibt. Dann gehören die nicht alle in ein Feld sondern in entsprechend veknüpfte Tabellen.
Antworten