id="co.plpgsql-porting-raise"/>
END IF;
DELETE FROM cs_active_job;
INSERT INTO cs_active_job(job_id) VALUES (v_job_id);
BEGIN
INSERT INTO cs_jobs (job_id, start_stamp) VALUES (v_job_id, now());
EXCEPTION
WHEN unique_violation THEN -- <co id="co.plpgsql-porting-exception"/>
-- don't worry if it already exists
END;
COMMIT;
END;
$$ LANGUAGE plpgsql;
</programlisting>
<calloutlist>
<callout arearefs="co.plpgsql-porting-raise">
<para>
The syntax of <literal>RAISE</literal> is considerably different from
Oracle's statement, although the basic case <literal>RAISE</literal>
<replaceable class="parameter">exception_name</replaceable> works
similarly.
</para>
</callout>
<callout arearefs="co.plpgsql-porting-exception">
<para>
The exception names supported by <application>PL/pgSQL</application> are
different from Oracle's. The set of built-in exception names
is much larger (see <xref linkend="errcodes-appendix"/>). There
is not currently a way to declare user-defined exception names,
although you can throw user-chosen SQLSTATE values instead.
</para>
</callout>
</calloutlist>
</para>
</example>
</sect2>
<sect2 id="plpgsql-porting-other">
<title>Other Things to Watch For</title>
<para>
This section explains a few other things to watch for when porting
Oracle <application>PL/SQL</application> functions to
<productname>PostgreSQL</productname>.
</para>
<sect3 id="plpgsql-porting-exceptions">
<title>Implicit Rollback after Exceptions</title>
<para>
In <application>PL/pgSQL</application>, when an exception is caught by an
<literal>EXCEPTION</literal> clause, all database changes since the block's
<literal>BEGIN</literal> are automatically rolled back. That is, the behavior
is equivalent to what you'd get in Oracle with:
<programlisting>
BEGIN
SAVEPOINT s1;
... code here ...
EXCEPTION
WHEN ... THEN
ROLLBACK TO s1;
... code here ...
WHEN ... THEN
ROLLBACK TO s1;
... code here ...
END;
</programlisting>
If you are translating an Oracle procedure that uses
<command>SAVEPOINT</command> and <command>ROLLBACK TO</command> in this style,
your task is easy: just omit the <command>SAVEPOINT</command> and
<command>ROLLBACK TO</command>. If you have a procedure that uses
<command>SAVEPOINT</command> and <command>ROLLBACK TO</command> in a different way
then some actual thought will be required.
</para>
</sect3>
<sect3 id="plpgsql-porting-other-execute">
<title><command>EXECUTE</command></title>
<para>
The <application>PL/pgSQL</application> version of
<command>EXECUTE</command> works similarly to the
<application>PL/SQL</application> version, but you have to remember to use
<function>quote_literal</function> and
<function>quote_ident</function> as described in <xref
linkend="plpgsql-statements-executing-dyn"/>. Constructs of the
type <literal>EXECUTE 'SELECT * FROM $1';</literal> will not work
reliably unless you use these functions.
</para>
</sect3>
<sect3 id="plpgsql-porting-optimization">
<title>Optimizing <application>PL/pgSQL</application> Functions</title>
<para>
<productname>PostgreSQL</productname> gives you two function creation
modifiers to optimize execution: <quote>volatility</quote> (whether
the function always returns the same result when given the same
arguments) and <quote>strictness</quote> (whether the function
returns null if any argument is null). Consult the <xref
linkend="sql-createfunction"/>
reference page for details.
</para>
<para>
When making use of these optimization