Einschließlich Variable in where-Klausel von arcpy.Select_analysis ()?

21

Ich versuche, ein Shapefile zu durchlaufen, indem ich nacheinander jedes Feature auswähle und es in ein temporäres Shapefile kopiere, um es in eine Vereinigungsanalyse einzubeziehen. Ich verwende einen Cursor, um den ID-Namen für jede Funktion zu finden, für die ich einen variablen 'Namen' festlegen möchte. Immer wenn ich versuche, diese Variable als Teil der where-Klausel in arcpy.Select_analysis zu verwenden, erhalte ich eine Fehlermeldung:

ExecuteError: ERROR 999999: Fehler beim Ausführen der Funktion. Eine ungültige SQL-Anweisung wurde verwendet. Eine ungültige SQL-Anweisung wurde verwendet. Fehler beim Ausführen (Auswählen).

Der Code, den ich benutze, ist:

Name = 101
where = "\'\"StudyID\" = \\'"+str(Name)+"\\'\'"
arcpy.Select_analysis("C:\\input.shp", "C:\\output.shp", where)

Wenn ich es ohne Verwendung der Variablen schreibe:

arcpy.Select_analysis("C:\\input.shp", "C:\\output.shp", '"StudyID" = \'101\'')

es funktioniert gut

Was muss ich tun, um die Variable in die SQL-Anweisung einzufügen?

Flo Harrison
quelle

Antworten:

14

Ein anderer, vielleicht einfacherer Weg ist:

where = '"StudyID" = ' + "'%s'" %Name
Marcin
quelle
2
"Bei Verwendung von ArcGIS 10 (oder möglicherweise später) müssen Feldnamen nicht in Anführungszeichen gesetzt werden." Dies ist falsch. Die Feldbegrenzer müssen gemäß den zugrunde liegenden DBMS-Syntaxregeln angegeben werden. Siehe meine Antwort.
blah238
Der obige Kommentar war eine Antwort auf eine anonyme Bearbeitung, die ich für die Richtigkeit dieser Antwort zurückgesetzt habe.
blah238
Handelt es sich nicht um eine SQL-Injection-Sicherheitsanfälligkeit, Namedie auf Benutzereingaben beruht?
jpmc26
22

Eine Sache, die das Schreiben von WHERE-Klauseln erheblich erleichtert, ist die Verwendung der AddFieldDelimitersFunktion, mit der automatisch die richtigen, DBMS-spezifischen Begrenzer für Feldbezeichner hinzugefügt werden, z. B. doppelte Anführungszeichen für FGDB und eckige Klammern für PGDB.

Sie müssen außerdem berücksichtigen, ob es sich bei dem Wert um eine Zahl, eine Zeichenfolge oder einen anderen Datentyp handelt. Insbesondere werden Zeichenfolgen in einfache Anführungszeichen gesetzt, Zahlen hingegen nicht. Sie können den Feldtyp überprüfen und einfache Anführungszeichen hinzufügen, wenn es sich um ein Zeichenfolgenfeld handelt.

Z.B:

import arcpy

def buildWhereClause(table, field, value):
    """Constructs a SQL WHERE clause to select rows having the specified value
    within a given field and table."""

    # Add DBMS-specific field delimiters
    fieldDelimited = arcpy.AddFieldDelimiters(table, field)

    # Determine field type
    fieldType = arcpy.ListFields(table, field)[0].type

    # Add single-quotes for string field values
    if str(fieldType) == 'String':
        value = "'%s'" % value

    # Format WHERE clause
    whereClause = "%s = %s" % (fieldDelimited, value)
    return whereClause

if __name__ == "__main__":
    inputfc = r"C:\input.shp"
    outputfc = r"C:\output.shp"
    fieldname = "StudyID"
    fieldvalue = 101
    whereclause = buildWhereClause(inputfc, fieldname, fieldvalue)
    arcpy.Select_analysis(inputfc, outputfc, whereclause)

Siehe auch die Funktion in dieser Antwort für eine mehrwertige Version der obigen Funktion.

blah238
quelle
2
Großartige Idee. Ich habe diese Funktion zu meinem Arcpy-Hilfsfunktionsmodul hinzugefügt, sodass sie als arcpy.buildWhereClause
blord-castillo
3

Versuche dies:

Name = 1
study = "StudyID"

where = '"' + study + '" = ' + "'" + str(Name) + "'"
Roy
quelle
0

Ich mag es, dreifache Anführungszeichen zu verwenden. Ich denke, sie sind am einfachsten zu lesen. Beispielsweise,

name = 101
where = """ "StudyID" = '%s' """ % name
arcpy.Select_analysis("C:\\input.shp", "C:\\output.shp", where)

Je nachdem, type(name)ob Sie die 'Umgebung benötigen oder nicht %s. Für Zahlen benötigen Sie das 'aber nicht für Text.

gisdude
quelle
0

Für mich funktioniert diese Lösung am besten, da ich sowohl eine Variable für das Interessengebiet als auch Wertkriterien ersetzen kann.

field = "Sport"
value = "Basketball"
where = """"{}" = '{}'""".format(field,value)
Dwiz
quelle