Incluyendo variable en la cláusula where de arcpy.Select_analysis ()?

21

Estoy tratando de recorrer un archivo de formas, seleccionando cada característica a su vez y copiándolas en un archivo de formas temporal para incluirlas en un análisis de unión. Estoy usando un cursor para encontrar el nombre de ID para cada función que estoy configurando en un 'Nombre' variable. Cada vez que intento usar esta variable como parte de la cláusula where en arcpy.Select_analysis obtengo un error:

ExecuteError: ERROR 999999: Error al ejecutar la función. Se utilizó una instrucción SQL no válida. Se utilizó una instrucción SQL no válida. Error al ejecutar (Seleccionar).

El código que estoy usando es:

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

Si lo escribo sin usar las variables:

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

funciona bien

¿Qué debo hacer para ajustar la variable en la instrucción sql?

Flo Harrison
fuente

Respuestas:

14

Otra forma, quizás más simple, es:

where = '"StudyID" = ' + "'%s'" %Name
Marcin
fuente
2
"Cuando se usa ArcGIS 10 (o, presumiblemente, más tarde), no es necesario citar los nombres de campo" Esto es incorrecto; los delimitadores de campo deben especificarse de acuerdo con las reglas de sintaxis del DBMS subyacente. Mira mi respuesta.
blah238
El comentario anterior fue en respuesta a una edición anónima que revertí para corregir esta respuesta.
blah238
¿No es esto una vulnerabilidad de inyección SQL si Nameproviene de la entrada del usuario?
jpmc26
22

Una cosa que hace que escribir cláusulas WHERE sea mucho más fácil es usar la AddFieldDelimitersfunción, que agrega automáticamente los delimitadores correctos, específicos de DBMS para identificadores de campo, como comillas dobles para FGDB y corchetes para PGDB.

La otra cosa que debe considerar es si el valor es un número, una cadena u otro tipo de datos. Específicamente, las cadenas se envuelven entre comillas simples, mientras que los números no. Puede verificar el tipo de campo y agregar comillas simples si es un campo de cadena.

P.ej:

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)

Consulte también la función en esta respuesta para obtener una versión de varios valores de la función anterior.

blah238
fuente
2
Gran idea. Agregué esta función a mi módulo de funciones de ayuda de arcpy para que se defina como arcpy.buildWhereClause
blord-castillo
3

Prueba esto:

Name = 1
study = "StudyID"

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

Me gusta usar comillas triples. Creo que son los más fáciles de leer. Por ejemplo,

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

Dependiendo de lo type(name)que pueda o no necesite el 'alrededor %s. Para los números, necesita el 'texto pero no el texto.

Gisdude
fuente
0

Para mí, esta solución funciona mejor, ya que puedo sustituir tanto una variable para el campo de interés como los criterios de valor.

field = "Sport"
value = "Basketball"
where = """"{}" = '{}'""".format(field,value)
dwiz
fuente