sql >> Databasteknik >  >> RDS >> PostgreSQL

Escape SQL LIKE-värde för Postgres med psycopg2

Ja, det här är en riktig röra. Både MySQL och PostgreSQL använder backslash-escapes för detta som standard. Detta är en fruktansvärd smärta om du också undslipper strängen igen med snedstreck istället för att använda parametrering, och det är också felaktigt enligt ANSI SQL:1992, som säger att det som standard inte finns några extra escape-tecken ovanpå normal sträng-escape, och därför inget sätt att inkludera en bokstavlig % eller _ .

Jag skulle anta att den enkla backslash-replace-metoden också blir fel om du stänger av backslash-escapes (som i sig inte är kompatibla med ANSI SQL), med NO_BACKSLASH_ESCAPE sql_mode i MySQL eller standard_conforming_strings conf i PostgreSQL (vilket PostgreSQL-utvecklarna har hotat att göra i ett par versioner nu).

Den enda riktiga lösningen är att använda den föga kända LIKE...ESCAPE syntax för att ange ett explicit escape-tecken för LIKE -mönster. Detta används istället för backslash-escape i MySQL och PostgreSQL, vilket gör att de överensstämmer med vad alla andra gör och ger ett garanterat sätt att inkludera out-of-band-karaktärerna. Till exempel med = tecken som en flykt:

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

Detta fungerar på PostgreSQL, MySQL och ANSI SQL-kompatibla databaser (modulo paramstilen, som ändras på olika db-moduler).

Det kan fortfarande finnas ett problem med MS SQL Server/Sybase, som tydligen också tillåter [a-z] -stilteckengrupper i LIKE uttryck. I det här fallet vill du också undkomma den bokstavliga [ tecken med .replace('[', '=[') . Men enligt ANSI SQL är escapening av ett tecken som inte behöver escape ogiltigt! (Argh!) Så även om det förmodligen fortfarande kommer att fungera över riktiga DBMS:er, skulle du fortfarande inte vara ANSI-kompatibel. suck...



  1. Fyller Many2many-fältet (odoo 8)

  2. Föråldrade funktioner att ta ur din verktygslåda – Del 1

  3. Hur kan jag skriva SQL för en tabell som har samma namn som ett skyddat nyckelord i MySql?

  4. Alfanumerisk sortering med PostgreSQL