Unless the function is declared to return
<type>void</type>, the last statement must be a <command>SELECT</command>,
or an <command>INSERT</command>, <command>UPDATE</command>,
<command>DELETE</command>, or <command>MERGE</command>
that has a <literal>RETURNING</literal> clause.
</para>
<para>
Any collection of commands in the <acronym>SQL</acronym>
language can be packaged together and defined as a function.
Besides <command>SELECT</command> queries, the commands can include data
modification queries (<command>INSERT</command>,
<command>UPDATE</command>, <command>DELETE</command>, and
<command>MERGE</command>), as well as
other SQL commands. (You cannot use transaction control commands, e.g.,
<command>COMMIT</command>, <command>SAVEPOINT</command>, and some utility
commands, e.g., <literal>VACUUM</literal>, in <acronym>SQL</acronym> functions.)
However, the final command
must be a <command>SELECT</command> or have a <literal>RETURNING</literal>
clause that returns whatever is
specified as the function's return type. Alternatively, if you
want to define an SQL function that performs actions but has no
useful value to return, you can define it as returning <type>void</type>.
For example, this function removes rows with negative salaries from
the <literal>emp</literal> table:
<screen>
CREATE FUNCTION clean_emp() RETURNS void AS '
DELETE FROM emp
WHERE salary < 0;
' LANGUAGE SQL;
SELECT clean_emp();
clean_emp
-----------
(1 row)
</screen>
</para>
<para>
You can also write this as a procedure, thus avoiding the issue of the
return type. For example:
<screen>
CREATE PROCEDURE clean_emp() AS '
DELETE FROM emp
WHERE salary < 0;
' LANGUAGE SQL;
CALL clean_emp();
</screen>
In simple cases like this, the difference between a function returning
<type>void</type> and a procedure is mostly stylistic. However,
procedures offer additional functionality such as transaction control
that is not available in functions. Also, procedures are SQL standard
whereas returning <type>void</type> is a PostgreSQL extension.
</para>
<para>
The syntax of the <command>CREATE FUNCTION</command> command requires
the function body to be written as a string constant. It is usually
most convenient to use dollar quoting (see <xref
linkend="sql-syntax-dollar-quoting"/>) for the string constant.
If you choose to use regular single-quoted string constant syntax,
you must double single quote marks (<literal>'</literal>) and backslashes
(<literal>\</literal>) (assuming escape string syntax) in the body of
the function (see <xref linkend="sql-syntax-strings"/>).
</para>
<sect2 id="xfunc-sql-function-arguments">
<title>Arguments for <acronym>SQL</acronym> Functions</title>
<indexterm>
<primary>function</primary>
<secondary>named argument</secondary>
</indexterm>
<para>
Arguments of an SQL function can be referenced in the function
body using either names or numbers. Examples of both methods appear
below.
</para>
<para>
To use a name, declare the function argument as having a name, and
then just write that name in the function body. If the argument name
is the same as any column name in the current SQL command within the
function, the column name will take precedence. To override this,
qualify the argument name with the name of the function itself, that is
<literal><replaceable>function_name</replaceable>.<replaceable>argument_name</replaceable></literal>.
(If this would conflict with a qualified column name, again the column
name wins. You can avoid the ambiguity by choosing a different alias for
the table within the SQL command.)
</para>
<para>
In the older numeric approach, arguments are referenced using the syntax
<literal>$<replaceable>n</replaceable></literal>: