Puedes usar el hash global %_SHARED para almacenar
datos, incluyendo referencias a código, entre llamadas a funciones durante la
vida de la sesión actual.
Aquí hay un ejemplo simple para datos compartidos:
CREATE OR REPLACE FUNCTION set_var(name text, val text) RETURNS text AS $$
if ($_SHARED{$_[0]} = $_[1]) {
return 'ok';
} else {
return "cannot set shared variable $_[0] to $_[1]";
}
$$ LANGUAGE plperl;
CREATE OR REPLACE FUNCTION get_var(name text) RETURNS text AS $$
return $_SHARED{$_[0]};
$$ LANGUAGE plperl;
SELECT set_var('sample', 'Hello, PL/Perl! How''s tricks?');
SELECT get_var('sample');
Aquí hay un ejemplo un poco más complicado que utiliza una referencia a código:
CREATE OR REPLACE FUNCTION myfuncs() RETURNS void AS $$
$_SHARED{myquote} = sub {
my $arg = shift;
$arg =~ s/(['\\])/\\$1/g;
return "'$arg'";
};
$$ LANGUAGE plperl;
SELECT myfuncs(); /* inicializa la función */
/* Define una función que use la función de entrecomillado */
CREATE OR REPLACE FUNCTION use_quote(TEXT) RETURNS text AS $$
my $text_to_quote = shift;
my $qfunc = $_SHARED{myquote};
return &$qfunc($text_to_quote);
$$ LANGUAGE plperl;
(Podrías haber reemplazado lo anterior con la línea única
return $_SHARED{myquote}->($_[0]);
a expensas de la legibilidad).
Por razones de seguridad, PL/Perl ejecuta las funciones llamadas por cualquier rol SQL
en un intérprete Perl separado para ese rol. Esto evita la interferencia accidental o
maliciosa de un usuario con el comportamiento de las funciones PL/Perl de otro
usuario. Cada uno de estos intérpretes tiene su propio valor de la
variable %_SHARED y otro estado global. Por lo tanto, dos
funciones PL/Perl compartirán el mismo valor de %_SHARED
si y solo si son ejecutadas por el mismo rol SQL. En una aplicación
donde una sola sesión ejecuta código bajo múltiples roles SQL (a través de
funciones SECURITY DEFINER, el uso de SET ROLE, etc.)
es posible que debas tomar medidas explícitas para asegurar que las funciones PL/Perl puedan
compartir datos a través de %_SHARED. Para hacer eso, asegúrate de que
las funciones que deben comunicarse sean propiedad del mismo usuario y márcalas como
SECURITY DEFINER. Por supuesto, debes tener cuidado de que
tales funciones no puedan usarse para hacer nada no deseado.