Syntax Error In Dynamic Sql In Pl/pgsql Function
Solution 1:
When creating a PL/pgSQL function, the function body is saved as string literal as is. Only superficial syntax checks are applied. Contained statements are not actually executed or tested on a deeper level.
However, basic syntax errors like you have in your query string would still be detected in actual SQL statements. But you are using dynamic SQL with EXECUTE. The statement is contained in a nested string literal and is your responsibility alone.
This seems to be misguided to begin with. There is no apparent reason for dynamic SQL. (Unless you have very uneven data distribution and want to force Postgres to generate a custom plan for each input value.)
If you had used a plain SQL statement, you would have gotten the error message at creation time:
CREATE OR REPLACE FUNCTION search_person(name text) -- still incorrect!
RETURNS TABLE(address_id integer, address_geom text, event_name text) AS
$func$
BEGIN
RETURN QUERY
SELECT address.id, event.name, address.geom
FROMeventJOIN person JOIN address JOIN person_address JOIN event_person
WHERE
person_address.event_id = event.id AND
event_person.event_id = event.id AND
person.id = event_person.person_id AND
person.name like $1; -- still $1, but refers to func param now!
END
$func$ LANGUAGE plpgsql;
The SQL statement is still invalid. [INNER] JOINrequires a join condition - like Nick commented. And I don't see the need for PL/pgSQL at all. A simple SQL function should serve well:
CREATE FUNCTION search_person(name text)
RETURNS TABLE(address_id integer, address_geom text, event_name text) AS
$func$
SELECT a.id, a.geom, e.name -- also fixed column orderto match return type
FROM person AS p
JOIN event_person AS ep ON ep.person_id = p.id
JOINeventAS e ON e.id = ep.event_id
JOIN person_address AS pa ON pa.event_id = e.id
JOIN address AS a ON a.id = pa.address_id -- missing join condition !!
WHERE p.name LIKE $1;
$func$ LANGUAGE sql;
I rewrote the query to fix syntax error, using table aliases for better readability. Finally, I also added one more missing condition based on an educated guess: a.id = pa.address_id.
Now it should work.
Related:
- plpgsql function not inserting data as intended
- Difference between language sql and language plpgsql in PostgreSQL functions
Or no function at all, just use a prepared statement instead. Example:
If you need dynamic SQL after all, pass values with the USING clause like you had it and make sure to defend against SQL injection when concatenating queries. Postgres provides various tools:
Post a Comment for "Syntax Error In Dynamic Sql In Pl/pgsql Function"