Inclusion de variable dans la clause where de arcpy.Select_analysis ()?


21

J'essaie de parcourir un fichier de formes, en sélectionnant chaque fonctionnalité à son tour et en la copiant dans un fichier de formes temporaire pour l'inclure dans une analyse d'union. J'utilise un curseur pour trouver le nom d'ID de chaque fonctionnalité que je définis sur un 'Nom' variable. Chaque fois que j'essaie d'utiliser cette variable dans le cadre de la clause where dans arcpy.Select_analysis, j'obtiens une erreur:

ExecuteError: ERREUR 999999: erreur lors de l'exécution de la fonction. Une instruction SQL non valide a été utilisée. Une instruction SQL non valide a été utilisée. Échec de l'exécution (Select).

Le code que j'utilise est:

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

Si je le tape sans utiliser les variables:

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

ça fonctionne bien

Que dois-je faire pour adapter la variable à l'instruction sql?

Réponses:


14

Un autre moyen, peut-être plus simple, est:

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

2
"Lors de l'utilisation d'ArcGIS 10 (ou, vraisemblablement, plus tard), les noms de champ n'ont pas besoin d'être cités" Ceci est incorrect; les délimiteurs de champ doivent être spécifiés conformément aux règles de syntaxe du SGBD sous-jacent. Voir ma réponse.
blah238

Le commentaire ci-dessus était en réponse à une modification anonyme que j'ai annulée pour l'exactitude de cette réponse.
blah238

N'est-ce pas une vulnérabilité d'injection SQL si elle Nameprovient d'une entrée utilisateur?
jpmc26

22

Une chose qui facilite beaucoup l'écriture des clauses WHERE est d'utiliser la AddFieldDelimitersfonction, qui ajoute automatiquement les délimiteurs spécifiques au SGBD pour les identificateurs de champ, tels que les guillemets doubles pour FGDB et les crochets pour PGDB.

L'autre chose que vous devez considérer est de savoir si la valeur est un nombre, une chaîne ou un autre type de données. Plus précisément, les chaînes sont entourées de guillemets simples, contrairement aux nombres. Vous pouvez vérifier le type de champ et ajouter des guillemets simples s'il s'agit d'un champ de chaîne.

Par exemple:

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)

Voir également la fonction dans cette réponse pour une version à plusieurs valeurs de la fonction ci-dessus.


2
Bonne idée. J'ai ajouté cette fonction à mon module de fonctions d'assistance arcpy afin qu'elle soit définie comme arcpy.buildWhereClause
blord-castillo

3

Essaye ça:

Name = 1
study = "StudyID"

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

0

J'aime utiliser des guillemets triples. Je pense qu'ils sont les plus faciles à lire. Par exemple,

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

En fonction de la, type(name)vous pouvez ou non avoir besoin de l' 'environnement %s. Pour les chiffres, vous avez besoin du 'mais pas du texte.


0

Pour moi, cette solution fonctionne le mieux car je peux substituer à la fois une variable au champ d'intérêt et des critères de valeur.

field = "Sport"
value = "Basketball"
where = """"{}" = '{}'""".format(field,value)
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.