PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

So maskieren Sie Zeichenfolgen beim Vergleichen von Mustern in PostgreSQL

Die Zeichen _ und % müssen in Anführungszeichen gesetzt werden, um in einer LIKE-Anweisung wörtlich gefunden zu werden, daran führt kein Weg vorbei. Die Wahl besteht darin, dies clientseitig oder serverseitig zu tun (normalerweise durch Verwendung von SQL replace(), siehe unten). Um es im allgemeinen Fall 100 % richtig zu machen, gibt es ein paar Dinge zu beachten.

Standardmäßig ist das vor _ oder % zu verwendende Anführungszeichen der Backslash (\), kann aber mit einer ESCAPE-Klausel unmittelbar nach der LIKE-Klausel geändert werden. In jedem Fall muss das Anführungszeichen zweimal im Muster bis wiederholt werden buchstäblich als ein Zeichen abgeglichen werden.

Beispiel:... WHERE field like 'john^%node1^^[email protected]%' ESCAPE '^' würde mit john%node1^[email protected] übereinstimmen gefolgt von allem.

Es gibt ein Problem mit der Standardauswahl des Backslash:Er wird bereits für andere Zwecke verwendet, wenn standard_conforming_strings auf OFF gesetzt ist (PG 9.1 hat ihn standardmäßig auf ON, aber frühere Versionen sind immer noch weit verbreitet, dies ist ein zu berücksichtigender Punkt).

Auch wenn das Zitieren für den LIKE-Platzhalter clientseitig in einem Benutzereingabe-Injection-Szenario erfolgt, kommt es zusätzlich zu zum normalen String-Quoting, das bereits bei Benutzereingaben erforderlich ist.

Ein Blick auf ein go-pgsql-Beispiel zeigt, dass es Platzhalter im $N-Stil für Variablen verwendet ... Hier ist also ein Versuch, es irgendwie generisch zu schreiben:Es funktioniert mit standard_conforming_strings sowohl ON als auch OFF, verwendet serverseitige Ersetzung von [%_], ein alternatives Anführungszeichen, das Anführungszeichen in Anführungszeichen setzen und SQL-Injection vermeiden:

   db.Query("SELECT * from USERS where name like replace(replace(replace($1,'^','^^'),'%','^%'),'_','^_') ||'%' ESCAPE '^'",
     variable_user_input);