Więc mam w moim Postgresql:
TAG_TABLE
==========================
id tag_name
--------------------------
1 aaa
2 bbb
3 ccc
Aby uprościć mój problem, chcę wybrać „id” z TAG_TABLE, gdy ciąg „aaaaaaaa” zawiera „nazwa_tagu”. Idealnie więc powinien zwrócić tylko „1”, czyli identyfikator dla nazwy tagu „aaa”
Oto, co robię do tej pory:
SELECT id FROM TAG_TABLE WHERE 'aaaaaaaaaaa' LIKE '%tag_name%'
Ale oczywiście to nie działa, ponieważ postgres uważa, że „% tag_name%” oznacza wzorzec zawierający podciąg „tag_name” zamiast rzeczywistej wartości danych pod tą kolumną.
Jak przekazać tag_name do wzorca?
sql
postgresql
user2436815
źródło
źródło
"; drop table TAG_TABLE; --"
?WHERE
klauzuli wynosiFALSE
. Instrukcja nie jest dynamiczna, tylko wartości są łączone, nie ma szans na wstrzyknięcie SQL.LIKE
słowa kluczowego.LIKE
wzorcu może mieć niezamierzone konsekwencje, gdy te zmienne zawierają podkreślenia (_) lub znaki procentu (%). Może być konieczna zmiana znaczenia tych znaków, na przykład za pomocą tej funkcji:CREATE OR REPLACE FUNCTION quote_for_like(text) RETURNS text LANGUAGE SQL IMMUTABLE AS $$ SELECT regexp_replace($1, '([\%_])', '\\\1', 'g'); $$;
(od użytkownika MatheusOl z kanału IRC #postgresql na Freenode).Osobiście wolę prostszą składnię operatora ~.
Warto przeczytać Różnicę między LIKE i ~ w Postgres, aby zrozumieć różnicę. `
źródło
tag_name
jest to właściwy REGEX. Dość ryzykowne.***=
której mowa w postgresql.org/docs/current/static/functions-matching.html . Jednak okazało się, że jest to zbyt wolniejsze w porównaniu z rozwiązaniamistrpos
/position
.Odpowiedni sposób wyszukać podciągu jest użycie
position
funkcji zamiastlike
wyrazu, który wymaga ucieczki%
,_
a charakter ucieczki (\
domyślnie):źródło
LIKE
iILIKE
potrafi używaćgin
indeksów.position
Nie mogę.Oprócz rozwiązania z
'aaaaaaaa' LIKE '%' || tag_name || '%'
there areposition
(odwrócona kolejność argumentów) istrpos
.Poza tym, co jest bardziej wydajne (LIKE wygląda na mniej wydajne, ale indeks może coś zmienić), istnieje bardzo drobny problem z LIKE: nazwa_tagu oczywiście nie powinien zawierać,
%
a zwłaszcza_
(pojedynczy znak wieloznaczny), aby nie dawać fałszywych alarmów.źródło
tag_name
powinno być w cudzysłowie, w przeciwnym razie zwróci błąd, ponieważ nazwa_tagu nie istniejeźródło