language,
to help developers who port applications from
<trademark class="registered">Oracle</trademark> to <productname>PostgreSQL</productname>.
</para>
<para>
<application>PL/pgSQL</application> is similar to PL/SQL in many
aspects. It is a block-structured, imperative language, and all
variables have to be declared. Assignments, loops, and conditionals
are similar. The main differences you should keep in mind when
porting from <application>PL/SQL</application> to
<application>PL/pgSQL</application> are:
<itemizedlist>
<listitem>
<para>
If a name used in an SQL command could be either a column name of a
table used in the command or a reference to a variable of the function,
<application>PL/SQL</application> treats it as a column name.
By default, <application>PL/pgSQL</application> will throw an error
complaining that the name is ambiguous. You can specify
<literal>plpgsql.variable_conflict</literal> = <literal>use_column</literal>
to change this behavior to match <application>PL/SQL</application>,
as explained in <xref linkend="plpgsql-var-subst"/>.
It's often best to avoid such ambiguities in the first place,
but if you have to port a large amount of code that depends on
this behavior, setting <literal>variable_conflict</literal> may be the
best solution.
</para>
</listitem>
<listitem>
<para>
In <productname>PostgreSQL</productname> the function body must be written as
a string literal. Therefore you need to use dollar quoting or escape
single quotes in the function body. (See <xref
linkend="plpgsql-quote-tips"/>.)
</para>
</listitem>
<listitem>
<para>
Data type names often need translation. For example, in Oracle string
values are commonly declared as being of type <type>varchar2</type>, which
is a non-SQL-standard type. In <productname>PostgreSQL</productname>,
use type <type>varchar</type> or <type>text</type> instead. Similarly, replace
type <type>number</type> with <type>numeric</type>, or use some other numeric
data type if there's a more appropriate one.
</para>
</listitem>
<listitem>
<para>
Instead of packages, use schemas to organize your functions
into groups.
</para>
</listitem>
<listitem>
<para>
Since there are no packages, there are no package-level variables
either. This is somewhat annoying. You can keep per-session state
in temporary tables instead.
</para>
</listitem>
<listitem>
<para>
Integer <command>FOR</command> loops with <literal>REVERSE</literal> work
differently: <application>PL/SQL</application> counts down from the second
number to the first, while <application>PL/pgSQL</application> counts down
from the first number to the second, requiring the loop bounds
to be swapped when porting. This incompatibility is unfortunate
but is unlikely to be changed. (See <xref
linkend="plpgsql-integer-for"/>.)
</para>
</listitem>
<listitem>
<para>
<command>FOR</command> loops over queries (other than cursors) also work
differently: the target variable(s) must have been declared,
whereas <application>PL/SQL</application> always declares them implicitly.
An advantage of this is that the variable values are still accessible
after the loop exits.
</para>
</listitem>
<listitem>
<para>
There are various notational differences for the use of cursor
variables.
</para>
</listitem>
</itemizedlist>
</para>
<sect2 id="plpgsql-porting-examples">
<title>Porting Examples</title>
<para>
<xref linkend="pgsql-porting-ex1"/> shows how to port a simple
function from <application>PL/SQL</application> to