Да, това е истинска бъркотия. И MySQL, и PostgreSQL използват обратна наклонена черта за това по подразбиране. Това е ужасна болка, ако също така избягвате отново низа с обратна наклонена черта, вместо да използвате параметризация, и също така е неправилно според ANSI SQL:1992, който казва, че по подразбиране няма допълнителни escape знаци отгоре на нормалното избягване на низ, и следователно няма начин да включите литерал %
или _
.
Предполагам, че простият метод за замяна с обратна наклонена черта също се обърка, ако изключите обратната наклонена черта-escapes (които сами по себе си не са съвместими с ANSI SQL), като използвате NO_BACKSLASH_ESCAPE
sql_mode в MySQL или standard_conforming_strings
conf в PostgreSQL (което разработчиците на PostgreSQL заплашват да направят от няколко версии).
Единственото истинско решение е да използвате малко познатия LIKE...ESCAPE
синтаксис за задаване на изричен escape символ за LIKE
-модел. Това се използва вместо обратната наклонена черта-escape в MySQL и PostgreSQL, което ги кара да отговарят на това, което правят всички останали, и дава гарантиран начин за включване на символите извън лентата. Например с =
знак като бягство:
# 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+'%'))
Това работи на PostgreSQL, MySQL и ANSI SQL-съвместими бази данни (разбира се по модула на стила на параметрите, който се променя в различни db модули).
Все още може да има проблем с MS SQL Server/Sybase, който очевидно също позволява [a-z]
-style групи от знаци в LIKE
изрази. В този случай бихте искали да избягате и от литерала [
знак с .replace('[', '=[')
. Въпреки това според ANSI SQL екранирането на символ, който не се нуждае от екраниране, е невалиден! (Argh!) Така че, въпреки че вероятно все още ще работи в реални СУБД, вие пак няма да сте съвместими с ANSI. въздишка...