Inclusa la variabile in cui la clausola di arcpy.Select_analysis ()?


21

Sto cercando di scorrere un file di forma, selezionando ciascuna funzione a sua volta e copiandola in un file di forma temporaneo da includere in un'analisi del sindacato. Sto usando un cursore per trovare il nome ID per ogni funzione che sto impostando su un 'Nome' variabile. Ogni volta che provo a utilizzare questa variabile come parte della clausola where in arcpy.Select_analysis ricevo un errore:

ExecuteError: ERROR 999999: errore nell'esecuzione della funzione. È stata utilizzata un'istruzione SQL non valida. È stata utilizzata un'istruzione SQL non valida. Impossibile eseguire (Seleziona).

Il codice che sto usando è:

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

Se lo scrivo senza usare le variabili:

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

funziona benissimo

Cosa devo fare per adattare la variabile all'istruzione sql?

Risposte:


14

Un altro modo, forse più semplice, è:

where = '"StudyID" = ' + "'%s'" %Name

2
"Quando si utilizza ArcGIS 10 (o, presumibilmente, in seguito), i nomi dei campi non devono essere citati" Questo non è corretto; i delimitatori di campo devono essere specificati in base alle regole di sintassi del DBMS sottostante. Vedi la mia risposta
blah238,

Il commento sopra era in risposta a una modifica anonima che ho ripristinato per la correttezza di questa risposta.
blah238,

Non è questa una vulnerabilità di SQL injection se Nameproviene dall'input dell'utente?
jpmc26

22

Una cosa che rende molto più semplice la scrittura delle clausole WHERE è l'uso della AddFieldDelimitersfunzione, che aggiunge automaticamente i delimitatori corretti specifici del DBMS per gli identificatori di campo, come virgolette doppie per FGDB e parentesi per PGDB.

L'altra cosa da considerare è se il valore è un numero, una stringa o un altro tipo di dati. In particolare, le stringhe sono racchiuse tra virgolette singole mentre i numeri non lo sono. È possibile controllare il tipo di campo e aggiungere virgolette singole se si tratta di un campo stringa.

Per esempio:

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)

Vedi anche la funzione in questa risposta per una versione multi-valore della funzione sopra.


2
Grande idea. Ho aggiunto questa funzione al mio modulo di funzioni di supporto arcpy in modo che sia definita come arcpy.buildWhereClause
blord-castillo

3

Prova questo:

Name = 1
study = "StudyID"

where = '"' + study + '" = ' + "'" + str(Name) + "'"

0

Mi piace usare le virgolette triple. Penso che siano i più facili da leggere. Per esempio,

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

A seconda del caso, type(name)potresti aver bisogno o meno del 'giro %s. Per i numeri, è necessario 'ma non per il testo.


0

Per me, questa soluzione funziona al meglio in quanto posso sostituire sia una variabile al campo di interesse sia criteri di valore.

field = "Sport"
value = "Basketball"
where = """"{}" = '{}'""".format(field,value)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.