Returning nothing
SQL commands are embedded into PL/pgSQL code
same as in expressions:
the query is prepared, PL/pgSQL variables become parameters
SELECT → PERFORM
convenient for calling functions with side effects
WITH queries should be wrapped into a SELECT
INSERT, UPDATE, DELETE and other SQL commands
except for service commands
transaction management: only in procedures and anonymous blocks
As we have already seen, PL/pgSQL is very closely integrated with SQL.
In particular, all expressions are computed using prepared SQL operators.
Besides, expressions can use PL/pgSQL variables and routine parameters:
they will be implicitly converted to query parameters.
SQL queries can also be executed within PL/pgSQL code. To execute a
query that returns no result (INSERT, UPDATE, DELETE, CREATE, DROP,
etc.), you just need to write an SQL command within the PL/pgSQL code as
a separate operator.
Commands are prepared exactly like expressions, with PL/pgSQL variables
used as parameters. It allows caching the parsed (or planned) query to
avoid repeating this work.
In a similar manner, you can also execute a regular SELECT statement if its
result is unimportant; simply replace the SELECT keyword with PERFORM.
It makes sense for cases like calling functions with side effects. WITH
queries have to be wrapped into a SELECT statement (so that it starts with
PERFORM when executed).
Service commands like VACUUM, REINDEX and others are not allowed in
routines.
COMMIT and ROLLBACK commands are allowed only in procedures and
anonymous blocks (executed by the SQL command DO).
https://postgrespro.com/docs/postgresql/17/plpgsql-statements#PLPGSQLS
TATEMENTS-GENERAL-SQL