Ya, ini benar-benar kacau. Baik MySQL dan PostgreSQL menggunakan garis miring terbalik untuk ini secara default. Ini adalah rasa sakit yang luar biasa jika Anda juga keluar dari string lagi dengan garis miring terbalik daripada menggunakan parameterisasi, dan itu juga salah menurut ANSI SQL:1992, yang mengatakan secara default tidak ada karakter pelarian tambahan di atas pelepasan string normal, dan karenanya tidak ada cara untuk memasukkan %
literal atau _
.
Saya akan menganggap metode backslash-replace sederhana juga salah jika Anda mematikan backslash-escapes (yang sendiri tidak sesuai dengan ANSI SQL), menggunakan NO_BACKSLASH_ESCAPE
sql_mode di MySQL atau standard_conforming_strings
conf di PostgreSQL (yang telah mengancam akan dilakukan oleh pengembang PostgreSQL untuk beberapa versi sekarang).
Satu-satunya solusi nyata adalah dengan menggunakan LIKE...ESCAPE
. yang tidak banyak diketahui orang sintaks untuk menentukan karakter pelarian eksplisit untuk LIKE
-pola. Ini digunakan sebagai ganti backslash-escape di MySQL dan PostgreSQL, membuatnya sesuai dengan apa yang dilakukan orang lain dan memberikan cara yang dijamin untuk memasukkan karakter out-of-band. Misalnya dengan =
tanda tangan sebagai pelarian:
# look for term anywhere within title
term= term.replace('=', '==').replace('%', '=%').replace('_', '=_')
sql= "SELECT * FROM things WHERE description LIKE %(like)s ESCAPE '='"
cursor.execute(sql, dict(like= '%'+term+'%'))
Ini berfungsi pada database yang sesuai dengan PostgreSQL, MySQL, dan ANSI SQL (tentu saja modulo paramstyle yang berubah pada modul db yang berbeda).
Mungkin masih ada masalah dengan MS SQL Server/Sybase, yang ternyata juga memungkinkan [a-z]
-gaya grup karakter dalam LIKE
ekspresi. Dalam hal ini Anda juga ingin keluar dari [
. literal karakter dengan .replace('[', '=[')
. Namun menurut ANSI SQL, melarikan diri dari karakter yang tidak perlu melarikan diri tidak valid! (Argh!) Jadi, meskipun mungkin masih berfungsi di DBMS nyata, Anda masih belum memenuhi persyaratan ANSI. hiks...