Entonces tengo un en mi Postgresql:
TAG_TABLE
==========================
id tag_name
--------------------------
1 aaa
2 bbb
3 ccc
Para simplificar mi problema, lo que quiero hacer es SELECCIONAR 'id' de TAG_TABLE cuando una cadena "aaaaaaaa" contiene el 'tag_name'. Entonces, idealmente, solo debería devolver "1", que es el ID para el nombre de etiqueta "aaa"
Esto es lo que estoy haciendo hasta ahora:
SELECT id FROM TAG_TABLE WHERE 'aaaaaaaaaaa' LIKE '%tag_name%'
Pero obviamente, esto no funciona, ya que postgres piensa que '% tag_name%' significa un patrón que contiene la subcadena 'tag_name' en lugar del valor de datos real en esa columna.
¿Cómo paso el tag_name al patrón?
sql
postgresql
usuario2436815
fuente
fuente
"; drop table TAG_TABLE; --"
?WHERE
cláusula se evalúa comoFALSE
. La declaración no es dinámica, solo los valores están concatenados, no hay posibilidad de inyección SQL.LIKE
palabra clave.LIKE
patrón puede tener consecuencias no deseadas cuando esas variables contienen guiones bajos (_) o caracteres de porcentaje (%). Puede ser necesario escapar de estos caracteres, por ejemplo con esta función:CREATE OR REPLACE FUNCTION quote_for_like(text) RETURNS text LANGUAGE SQL IMMUTABLE AS $$ SELECT regexp_replace($1, '([\%_])', '\\\1', 'g'); $$;
(del usuario MatheusOl del canal de IRC #postgresql en Freenode).Personalmente prefiero la sintaxis más simple del operador ~.
Vale la pena leer Diferencia entre LIKE y ~ en Postgres para comprender la diferencia. '
fuente
tag_name
es un REGEX adecuado. Bastante arriesgado.***=
que se menciona en postgresql.org/docs/current/static/functions-matching.html . Sin embargo, he descubierto que es mucho más lento en comparación constrpos
/position
solutions.Una forma adecuada de buscar una subcadena es usar la
position
función en lugar de lalike
expresión, lo que requiere escapar%
,_
y un carácter de escape (\
por defecto):fuente
LIKE
yILIKE
puede utilizargin
índices.position
no puedo.Además de la solución con
'aaaaaaaa' LIKE '%' || tag_name || '%'
hayposition
(orden inverso de argumentos) ystrpos
.Además de lo que es más eficiente (LIKE parece menos eficiente, pero un índice puede cambiar las cosas), hay un problema menor con LIKE: tag_name por supuesto no debería contener
%
y especialmente_
(comodín de carácter único), para no dar falsos positivos.fuente
tag_name
debe estar entre comillas, de lo contrario, dará un error ya que el nombre de la etiqueta no existefuente