patternsqlMinor
Wildcard search using parameters in function with dynamic SQL
Viewed 0 times
wildcardsearchwithsqlfunctionusingdynamicparameters
Problem
What is the proper way to implement a wildcard search in PostgreSQL when using a parameter in a function that uses dynamic SQL?
As a starting point, here is an example from Erwin Brandstetter answering a different question on Stackoverflow:
https://stackoverflow.com/a/12047277/538962
Let's suppose for
E.g., without using a parameter,
What is the best way to implement the wildcard search be in this scenario with respect to negating SQL injection risk?
I am currently using PostgreSQL 9.5.1.
As a starting point, here is an example from Erwin Brandstetter answering a different question on Stackoverflow:
https://stackoverflow.com/a/12047277/538962
CREATE OR REPLACE FUNCTION report_get_countries_new (starts_with text
, ends_with text = NULL)
RETURNS SETOF lookups.countries AS
$func$
DECLARE
sql text := 'SELECT * FROM lookups.countries WHERE country_name >= $1';
BEGIN
IF ends_with IS NOT NULL THEN
sql := sql || ' AND country_name <= $2';
END IF;
RETURN QUERY EXECUTE sql
USING starts_with, ends_with;
END
$func$ LANGUAGE plpgsql;Let's suppose for
country_name you wanted to do a leading and trailing wildcard search.E.g., without using a parameter,
AND country_name LIKE '%ic%'.What is the best way to implement the wildcard search be in this scenario with respect to negating SQL injection risk?
I am currently using PostgreSQL 9.5.1.
Solution
Let's suppose for
You don't need dynamic SQL for this. Just:
Call:
This negates SQL-injection risk completely, which comes with dynamic SQL.
The caller can still include wildcards at will (unless you process the parameter to filter wildcards), but there is a hardcoded leading wildcard and also a trailing one (unless the parameter ends with
Even if you work with dynamic SQL and
Related:
country_name you wanted to do a leading and trailing wildcard search.You don't need dynamic SQL for this. Just:
CREATE OR REPLACE FUNCTION report_get_countries_new (_pattern text)
RETURNS SETOF lookups.countries
LANGUAGE sql AS
$func$
SELECT *
FROM lookups.countries
WHERE country_name LIKE '%' || _pattern || '%'
$func$;Call:
SELECT * FROM report_get_countries_new ('ic'); -- no wildcards!This negates SQL-injection risk completely, which comes with dynamic SQL.
The caller can still include wildcards at will (unless you process the parameter to filter wildcards), but there is a hardcoded leading wildcard and also a trailing one (unless the parameter ends with
\ removing the special meaning from the trailing %).Even if you work with dynamic SQL and
EXECUTE in PL/pgSQL, there is no risk for SQL injection as long as you pass values as values with the USING clause:Related:
- SQL injection in Postgres functions vs prepared queries
- Function Performance
- Table name as a PostgreSQL function parameter
Code Snippets
CREATE OR REPLACE FUNCTION report_get_countries_new (_pattern text)
RETURNS SETOF lookups.countries
LANGUAGE sql AS
$func$
SELECT *
FROM lookups.countries
WHERE country_name LIKE '%' || _pattern || '%'
$func$;SELECT * FROM report_get_countries_new ('ic'); -- no wildcards!Context
StackExchange Database Administrators Q#134826, answer score: 9
Revisions (0)
No revisions yet.