Termasuk variabel di mana klausa arcpy.Select_analysis ()?

21

Saya mencoba untuk mengulang melalui shapefile, memilih masing-masing fitur pada gilirannya dan menyalinnya ke shapefile sementara dengan dimasukkan dalam analisis gabungan. Saya menggunakan kursor untuk menemukan nama ID untuk setiap fitur yang saya atur ke variabel 'Nama'. Setiap kali saya mencoba menggunakan variabel ini sebagai bagian dari klausa di mana di arcpy.Select_analysis saya mendapatkan kesalahan:

ExecuteError: ERROR 999999: Fungsi eksekusi kesalahan. Pernyataan SQL yang tidak valid digunakan. Pernyataan SQL yang tidak valid digunakan. Gagal menjalankan (Pilih).

Kode yang saya gunakan adalah:

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

Jika saya mengetiknya tanpa menggunakan variabel:

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

ini bekerja dengan baik

Apa yang harus saya lakukan agar sesuai dengan variabel ke dalam pernyataan sql?

Flo Harrison
sumber

Jawaban:

14

Cara lain yang mungkin lebih sederhana adalah:

where = '"StudyID" = ' + "'%s'" %Name
Marcin
sumber
2
"Saat menggunakan ArcGIS 10 (atau, mungkin, nanti), nama-nama bidang tidak perlu dikutip" Ini tidak benar; pembatas bidang harus ditentukan sesuai dengan aturan sintaks DBMS yang mendasarinya. Lihat jawaban saya.
blah238
Komentar di atas adalah tanggapan terhadap suntingan anonim yang saya gulung balik untuk kebenaran jawaban ini.
blah238
Bukankah ini kerentanan injeksi SQL jika Nameberasal dari input pengguna?
jpmc26
22

Satu hal yang membuat penulisan WHERE klausa jauh lebih mudah adalah menggunakan AddFieldDelimitersfungsi, yang secara otomatis menambahkan pembatas khusus DBMS yang tepat untuk pengidentifikasi bidang, seperti tanda kutip ganda untuk FGDB dan tanda kurung untuk PGDB.

Hal lain yang harus Anda pertimbangkan adalah apakah nilainya berupa angka, string, atau tipe data lainnya. Secara khusus, string dibungkus dengan tanda kutip tunggal sedangkan angka tidak. Anda bisa memeriksa jenis bidang dan menambahkan tanda kutip tunggal jika itu adalah bidang string.

Misalnya:

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)

Lihat juga fungsi dalam jawaban ini untuk versi multi-nilai dari fungsi di atas.

blah238
sumber
2
Ide yang hebat. Saya menambahkan fungsi ini ke modul fungsi pembantu helper saya sehingga didefinisikan sebagai arcpy.buildWhereClause
blord-castillo
3

Coba ini:

Name = 1
study = "StudyID"

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

Saya suka menggunakan tiga kutipan. Saya pikir mereka yang paling mudah dibaca. Sebagai contoh,

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

Tergantung pada type(name)Anda mungkin perlu atau tidak perlu 'sekitar %s. Untuk angka, Anda perlu 'tetapi tidak untuk teks.

gisdude
sumber
0

Bagi saya, solusi ini bekerja paling baik karena saya bisa mengganti variabel dengan bidang minat dan kriteria nilai.

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