sql >> Databáze >  >> RDS >> PostgreSQL

Unikněte z hodnoty LIKE SQL pro Postgres pomocí psycopg2

Jo, tohle je fakt průšvih. MySQL i PostgreSQL k tomu standardně používají zpětné lomítko. To je strašná bolest, pokud také znovu escapujete řetězec pomocí zpětných lomítek místo použití parametrizace, a je to také nesprávné podle ANSI SQL:1992, která říká, že ve výchozím nastavení neexistují žádné další únikové znaky nad normálním escapováním řetězce, a proto není možné zahrnout doslovné % nebo _ .

Předpokládal bych, že jednoduchá metoda nahrazování zpětným lomítkem se také pokazí, pokud vypnete úniky zpětným lomítkem (které samy nejsou kompatibilní s ANSI SQL) pomocí NO_BACKSLASH_ESCAPE sql_mode v MySQL nebo standard_conforming_strings conf v PostgreSQL (což vývojáři PostgreSQL nyní hrozili, že udělají několik verzí).

Jediným skutečným řešením je použití málo známého LIKE...ESCAPE syntaxe k určení explicitního znaku escape pro LIKE -vzor. To se používá místo zpětného lomítka v MySQL a PostgreSQL, čímž se přizpůsobí tomu, co dělají všichni ostatní, a poskytuje zaručený způsob, jak zahrnout znaky mimo pásmo. Například pomocí = podepsat jako únik:

# 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+'%'))

Toto funguje na databázích kompatibilních s PostgreSQL, MySQL a ANSI SQL (modulo paramstyle samozřejmě, který se mění na různých db modulech).

Stále může být problém s MS SQL Server/Sybase, který zjevně také umožňuje [a-z] -style skupiny znaků v LIKE výrazy. V tomto případě byste také chtěli uniknout doslovnému [ znak s .replace('[', '=[') . Nicméně podle ANSI SQL je escapování znaku, který nepotřebuje escapování, neplatné! (Argh!) Takže ačkoli to bude pravděpodobně stále fungovat ve skutečných DBMS, stále byste nebyli kompatibilní s ANSI. povzdech...



  1. Vytvořte pohled s klauzulí ORDER BY

  2. Jak používáte proměnné skriptu v psql?

  3. Co je s (nolock) na serveru SQL?

  4. Co představuje double v SQL serveru?