Ich weiß, wie man eine Liste einer Zeichenfolge zuordnet:
foostring = ",".join( map(str, list_of_ids) )
Und ich weiß, dass ich Folgendes verwenden kann, um diesen String in eine IN-Klausel zu bekommen:
cursor.execute("DELETE FROM foo.bar WHERE baz IN ('%s')" % (foostring))
Was ich brauche, ist das gleiche mit SASELD (Vermeidung von SQL-Injection) mit MySQLDB zu erreichen. Im obigen Beispiel ist Foostring anfällig, da es nicht als Argument für die Ausführung übergeben wird. Ich muss auch außerhalb der MySQL-Bibliothek zitieren und fliehen.
(Es gibt eine verwandte SO-Frage , aber die dort aufgeführten Antworten funktionieren entweder nicht für MySQLDB oder sind anfällig für SQL-Injection.)
Antworten:
Verwenden Sie die
list_of_ids
direkt:Auf diese Weise vermeiden Sie, dass Sie sich selbst zitieren müssen, und vermeiden alle Arten von SQL-Injektionen.
Beachten Sie, dass die Daten (
list_of_ids
) als Parameter (nicht im Abfragetext) direkt an den MySQL-Treiber gesendet werden, sodass keine Injektion erfolgt. Sie können beliebige Zeichen in der Zeichenfolge belassen, ohne Zeichen entfernen oder zitieren zu müssen.quelle
?
nicht%s
so, dass es funktionieren würde, wenn Sie die erste Zeile in ändernformat_strings = ','.join('?' * len(list_of_ids))
.% format_strings
Teil die anderen%s
Platzhalter in Ihrer Abfrage ändert, sondern nur denIN (%s)
Platzhalter. - Um dies zu erreichen, verdoppeln Sie alle%
Zeichen außer dem, das Sie ersetzen möchten:query = ("select distinct cln from vcf_commits where branch like %%s and repository like %%s and filename in (%s) and author not like %%s" % format_strings,); cursor.execute(query, (branch, repository) + tuple(fname_list) + (invalid_author,))
Obwohl diese Frage ziemlich alt ist, dachte ich, es wäre besser, eine Antwort zu hinterlassen, falls jemand anderes nach dem sucht, was ich wollte
Akzeptierte Antworten werden unübersichtlich, wenn wir viele Parameter haben oder benannte Parameter verwenden möchten
Nach einigen Versuchen
Getestet mit
python2.7
,pymysql==0.7.11
quelle
Wenn Sie
Django 2.0 or 2.1
und verwendenPython 3.6
, ist dies der richtige Weg:Ref: https://stackoverflow.com/a/23891759/2803344 https://docs.djangoproject.com/de/2.1/topics/db/sql/#passing-parameters-into-raw
quelle
Obwohl diese Frage ziemlich alt ist. Ich teile meine Lösung, wenn sie jemandem helfen kann.
list_to_check = ['A', 'B'] cursor.execute("DELETE FROM foo.bar WHERE baz IN ({})".format(str(list_to_check)[1:-1])
Getestet mit
Python=3.6
quelle
list_to_check
nicht SQL-Escape ist. Aus diesem Grundexecute
ist es besser , die Werte als Parameter an zu übergeben . Verwenden Sie diese Lösung sehr vorsichtig (dh die Eingabe-IDs werden nicht als Parameter von außerhalb Ihrer Anwendung empfangen), da dies jemand verwenden könnte, um Ihr System anzugreifen und auf Ihre Datenbank zuzugreifen.Eine weitere einfache Lösung mit Listenverständnis:
quelle
Dies kann in einigen Anwendungsfällen funktionieren, wenn Sie sich nicht mit der Methode befassen möchten, bei der Sie Argumente übergeben müssen, um die Abfragezeichenfolge zu vervollständigen, und nur aufrufen möchten
cursror.execute(query)
.Ein anderer Weg könnte sein:
quelle
Sehr einfach: Verwenden Sie einfach die folgende Formation
rules_id = ["9", "10"]
sql1 = "SELECT * FROM Anwesenheitsregeln_Staff WHERE ID in (" + "," .join (map (str, rules_id)) + ")"
"," .join (map (str, rules_id))
quelle
rules_id
enthält"); DROP TABLES Bobby --
?