Professional Documents
Culture Documents
El PL_pgSQL es una herramienta de complemento para el SQL ya que este es un lenguaje estndar para la realizacin de consultas a un servidor de base de datos, el PL_pgSQL guarda mucha similitud con el lenguaje de Oracle PL_SQL. Segn Roberto Andrade Fonseca. ABL Consultores, S.A. de C.V. en su publicacin de 8 de Febrero de 2002; este explica que el PL_pgSQL es bastante fcil de utilizar, con el presente manual se dar a entender las sentencias mas frecuentes utilizadas para esta herramienta. Se tomaran ejemplos referenciales de las publicaciones de Roberto Andrade Fonseca Febrero del ao 2002 para la elaboracin del manual PL_pgSQL.y de igualmanera se tomaran ejemplos de la publicacin de Javier Jofre Gonzlez-Granda Junio del ao 2004.
1 comilla
Para iniciar y finalizar el cuerpo de la funcin, por ejemplo: CREATE FUNCTION foo() RETURNS integer AS .... LANGUAGE plpgsql; En cualquier lugar dentro del cuerpo de la funcin delimitada por una comilla, las comillas deben aparecer en pares.
2 comillas
Para cadenas literales dentro del cuerpo de la funcin, por ejemplo: a_output := Blah; SELECT * FROM users WHERE f_name=foobar; Usando la tcnica de $$, usted debera escribir a_output := Blah; SELECT * FROM users WHERE f_name=foobar; que es exactamente lo que el analizador de PL/pgSQL vera en ambos casos.
4 comillas
Cuando requiera una comilla sencilla en una cadena constante dentro del cuerpo de la funcin, por ejemplo; a_output := a_output || AND name LIKE foobar AND xyz El valor realmente concatenado a a_output sera: AND name LIKE foobar AND xyz.Usando la tcnica de $$, usted escribira: a_output := a_output || $$ AND name LIKE foobar AND xyz$$ teniendo cuidado de que cualquiera de los delimitadores estilo dlar alrededor de esta cadena no sea ciertamente $$.
6 comillas
Cuando una comillas sencilla en una cadena dentro del cuerpo de la funcin sea adyacente al final de la cadena constante, por ejemplo: a_output := a_output || AND name LIKE foobar El valor concatenado a a_output sera entonces: AND name LIKE foobar. Con el estilo dlar se transformara en: a_output := a_output || $$ AND name LIKE foobar$$
10 comillas
Cuando requiera dos comillas sencillas en una cadena constante (que equivalen a 8 comillas) y sta es adyacente al final de la cadena constante (2 ms). Es probable que solamente necesite esto si est escribiendo una funcin que genera otras funciones. Por ejemplo: a_output := a_output || if v_ || referrer_keys.kind || like || referrer_keys.key_string || then return || referrer_keys.referrer_type || ; end if;; El valor de a_output sera entonces: if v_... like ... then return ...; end if; Con el estilo dlar quedara como a_output := a_output || $$ if v_$$ || referrer_keys.kind || $$ like $$ || referrer_keys.key_string || $$ then return $$ || referrer_keys.referrer_type || $$; end if;$$; en donde suponemos que solamente requerimos colocar una comilla dentro de a_output debido a que ser re-encomillado antes de usarse. Una variante es el escapar las comillas en el cuerpo de la funcin con una diagonal invertida en lugar de duplicarlas. Con este mtodo escribira cosas como \\ en lugar de . Algunas personas consideran esta tcnica ms sencilla, pero otras no.
La Estructura de PL/pgSQL
PL/pgSQL es un lenguaje estructurado a base de bloques. El texto completo de la definicin de una funcin debe ser un bloque. Un bloque est definido como: [ <<etiqueta>> ] [ DECLARE declaraciones ] BEGIN sentencias END; Cada declaracin y cada sentencia dentro de un bloque deben terminar con punto y coma. Un bloque que aparece dentro de otro bloque debe contar con un punto y coma despus de END, como se muestra abajo; sin embargo, el END final que cierra el cuerpo de una funcin no requiere el punto y coma. Todas la palabras reservadas y los identificadores pueden escribirse en maysculas, minsculas o una mezcla de ellas. Los identificadores son convertidos implicitamente a minsculas, a menos que estn encerradas en comillas dobles. Existen dos tipos de comentarios en PL/pgSQL. Un doble guin (--) marca el inicio de un comentario que se extiende hasta el final de la lnea. Los smbolos /* marcan el inicio de un bloque de un comentario que se extiende hasta la aparicin de /*. Los bloques de comentarios no pueden anidarse, pero los comentarios con doble guin pueden ocultar los delimitadores de un bloque de un comentario /* y */. Cualquier sentencia en la seccin de sentencias de un bloque puede ser un subbloque. Los subbloques pueden usarse para agrupamientos lgicos o para hacer locales las variables de un grupo de sentencias. Las variables declaradas en la seccin de declaraciones que precede a un bloque son inicializadas a su valor por omisin cada vez que se entra al bloque, no solamente una vez por llamada a la funcin. Por ejemplo: CREATE FUNCTION somefunc() RETURNS integer AS $$ DECLARE quantity integer := 30; BEGIN RAISE NOTICE Aqu, cantidad tiene el valor de %, quantity; -- Aqu, cantidad tiene el valor de 30 quantity := 50; --- Creamos un subbloque -DECLARE quantity integer := 80; BEGIN RAISE NOTICE Aqu, cantidad tiene el valor de %, quantity; -- Aqu, cantidad tiene el valor de 80 END; RAISE NOTICE Aqu, cantidad tiene el valor de %, quantity; -- Aqu, cantidad tiene el valor de 50 RETURN quantity; END; $$ LANGUAGE plpgsql; 4
Es importante no confundir el uso de BEGIN/END para agrupar sentencias en PL/pgSQL con los comandos de la base de datos para el control de las transacciones. Los comandos BEGIN/END de PL/pgSQL se usan solamente para agrupar; no inician ni terminan una transaccin. Las funciones y los procedimientos disparadores (trigger) siempre son ejecutados dentro de una transaccin establecida por una consulta externa no pueden iniciar o hacer que se ejecute un commit de esa transaccin, puesto que no existe un contexto para su ejecucin. Sin embargo, un bloque que contenga una clasula de EXCEPTION s genera una subtransaccin que puede echarse atrs (rolled back) sin afectar la transaccin externa. Para ms detalles puede ver la seccin de nombre Atrapar los Errores.
Declaraciones
Todas las variables usadas en un bloque deben ser declaradas en la seccin de declaraciones de ese bloque. (La nica excepcin es que la variable ndice de un ciclo FOR que itera sobre un rango de valores enteros es declarada automticamente como una variable entera). Las variables de PL/pgSQL pueden tener cualquier tipo de dato de SQL, tales como integer, varchar y char. Estos son algunos ejemplos de la declaracin de variables: user_id integer; cantidad numeric(5); url varchar; myrenglon nombretabla%ROWTYPE; mycampo nombretabla.nombrecolumna%TYPE; unrenglon RECORD; La sintaxis general de la declaracin de una variable es: nombre [ CONSTANT ] tipo [ NOT NULL ] [ { DEFAULT | := } expresin ]; La clusula DEFAULT, cuando existe, especifica el valor inicial asignado a la variable cuando se ingresa al bloque. Si la clasula DEFAULT no existe entonces la variable se inicializa al valor nulo de SQL. Si se especifica NOT NULL, la asignacin de un valor nulo dar por resultado un error en tiempo de ejecucin. Todas las variable declaradas como NOT NULL deben tener especificado un valor no nulo. El valor por omisin se evala cada vez que se entra al bloque. As, por ejemplo, el asignar now() a la variable de tipo timestamp causar que esa variable tenga la hora de la llamada a la funcin actual, no la hora en que la funcin fue precompilada. Ejemplos: cantidad integer DEFAULT 32; url varchar := http://misitio.com; user_id CONSTANT integer := 10;
Copiando Tipos
variable%TYPE %TYPE proporciona el tipo de dato de una variable o de una columna de una tabla. Puede utilizarla para declarar variables que almacenarn valores de la base de datos. Por ejemplo, supongamos que tiene una columna llamada id_usuario en su tabla usuarios. Para declarar una variable con el mismo tipo de dato que usuarios.id_usuario usted escribira: id_usuario usuarios.id_usuario%TYPE; Al usar %TYPE no necesita conocer el tipo de dato de la estructura a la que est haciendo referencia, y lo ms importante, si el tipo de dato del tem referido cambia en algn momento en el futuro (por ejemplo: si cambia el tipo de id_usuario de integer a real), usted no necesita cambiar la definicin en su funcin. %TYPE es particularmente til en las funciones polimrficas, puesto que los tipos de datos necesarios para las variables internas puede cambiar de una llamada a otra. Se pueden crear variables apropiadas aplicando %TYPE a los argumentos o a los comodines de los resultados de la funcin.
Tipos Rengln
nombre nombre_tabla%ROWTYPE; nombre nombre_tipo_compuesto; Una variable de un tipo compuesto se denomina una variable rengln (o tipo-renglon). Dicha variable puede almacenar un rengln completo resultado de una consulta SELECT o FOR, en tanto el conjunto de columnas de la consulta coincida con el tipo de la variable declarado. Los campos individuales del valor del rengln pueden accederse usando la notacin usual de punto, por ejemplo renglonvar.campo. Una variable rengln puede declararse para tener el mismo tipo que los renglones de una tabla o vista existente, usando la notacin nombre_tabla%ROWTYPE; o puede ser declarada dando el nombre de un tipo compuesto. (Puesto que todas las tablas tiene un tipo compuesto asociado del mismo nombre, en PostgreSQL realmente no importa si escribe %ROWTYPE o no. Pero la forma con %ROWTYPE es ms portable). Los parmetros de una funcin pueden ser de tipo compuesto (renglones de tablas completos). En ese caso, el identificador correspondiente $n ser un variable rengln, y pueden seleccionarse los campos a partir de l, por ejemplo $1.id_usuario. En una variable tipo-rengln, solamente son accesibles las columnas definidas por el usuario, no el OID u otras columnas del sistema (debido a que el rengln podra ser de una vista). Los campos del tipo rengln heredan el tamao o la precisin del campo de la tabla para datos tales como char(n).
Este es un ejemplo del uso de los tipos compuestos: CREATE FUNCTION merge_fields(t_row tablename) RETURNS text AS $$ DECLARE t2_row table2name%ROWTYPE; BEGIN SELECT * INTO t2_row FROM table2name WHERE ... ; RETURN t_row.f1 || t2_row.f3 || t_row.f5 || t2_row.f7; END; $$ LANGUAGE plpgsql; SELECT merge_fields(t.*) FROM tablename t WHERE ... ;
Tipos Registro
nombre RECORD; Las variables registro son similares a las variables tipo-rengln, pero no tienen una estructura predefinida. Toman la estructura actual del rengln al que son asignados durante un comando SELECT o FOR. La subestructura de una variable registro puede cambiar cada vez que es asignada. Una consecuencia de sto es que mientras una variable registro no sea asignada por primera vez, no tendr subestructura y cualquier intento de acceder a uno de sus campos generar un error en tiempo de ejecucin. Observe que RECORD no es realmente un tipo de dato, sino un comodn. Tambin debe darse cuenta que cuando una funcin PL/pgSQL se declara para regresar un tipo record, no es lo mismo que una variable registro, aunque tal variable pueda utilizar una variable registro para almacenar su resultado. En ambos casos la estructura actual del rengln es desconocida cuando se escribe la funcin, pero para una funcin que regresa un record la estructura actual se determina cuando se analiza la consulta solicitada, mientras que una variable record puede cambiar su estructura de renglnal instante.
Expresiones
Todas las expresiones usadas en sentencias de PL/pgSQL son procesadas usando el ejecutor SQL regular del servidor. De hecho, una consulta como SELECT expresin se ejecuta usando al administrador SPI. Antes de la evaluacin, las ocurrencias de los identificadores de variables de PL/pgSQL son reemplazados por los parmetros y el valor actual de las variables se pasa al ejecutor en el arreglo de parmetros. Esto permite que el plan de la consulta del SELECT sea preparado solamente una vez y despus reutilizado para las evaluaciones subsecuentes. La evaluacin hecha por el analizador (parser) pricipal de PostgreSQL tiene algunos efectos secundarios en la interpretacin de los valores constantes. En detalle existen diferencias entre lo que hacen estas dos funciones:
CREATE FUNCTION logfunc1(logtxt text) RETURNS timestamp AS $$ BEGIN INSERT INTO logtable VALUES (logtxt, now); RETURN now; END; $$ LANGUAGE plpgsql;
Y
CREATE FUNCTION logfunc2(logtxt text) RETURNS timestamp AS $$ DECLARE curtime timestamp; BEGIN curtime := now; INSERT INTO logtable VALUES (logtxt, curtime); RETURN curtime; END; $$ LANGUAGE plpgsql;
En en caso de logfunc1, el analizador principal de PostgreSQL sabe cuando preparar el plan para el INSERT, que la cadena now debe interpretarse como timestamp debido a que su columna objetivo de logtable es de ese tipo. As, crear una constante con ella en este momento y su valor constante ser utilizado en todas las invocaciones de logfunc1 durante la vida de la sesin. No es necesario decir que esto no es lo que el programador deseaba hacer En el caso de logfunc2, el analizador principal de PostgreSQL no sabe que tipo debe tener now y entonces regresa un valor de tipo text que contiene la cadena now. Durante la asignacin subsiguiente a la variable local curtime, el intrprete de PL/pgSQL transforma esta cadena al tipo timestamp llamando a las funciones text_out y timestamp_in para la conversin. As, la hora y la fecha calculadas en cada ejecucin es la que espera el programador La naturaleza mutable de las variables registro presentan un problema en este mbito. Cuando los campos de una variable registro son usados en expresiones o sentencias, los tipos de datos de los campos no deben cambiar entre llamadas de una misma expresin, puesto que la expresin ser planeada usando los tipos de dato que estn presentes cuando la expresin sea alcanzada por primera vez. Tenga en cuenta esto al escribir procedimientos disparadores que manejen eventos para ms de una tabla.(Cuando se necesario, puede utilizar EXECUTE para evitar este problema). 9
Asignacin
Una asignacin de una valor a una variable o campo de un rengln/registro se escribe como: identificador := expresin; Tal como se escribi arriba, la expresin en tal sentencia es evaluada por medio de un comando SQL SELECT enviado a la mquina de la base de datos principal. La expresin debe producir un valor nico. Si el tipo de dato del resultado de la expresin no coincide con el tipo de dato de la variable, o la variable tiene un tamao/precisin especfico (como char(20)), el valor resultante ser convertido implcitamente por el intrprete de PL/pgSQL usando el tipo de resultado de la funcin de salida (output_function) y el tipo de variable de la funcin de entrada (input_function). Observe que esto puede resultar potencialmente en un error en tiempo de ejecucin generado por la funcin de entrada, si la forma de la cadena del valor resultante no es aceptable para la funcin de entrada. Ejemplos: id_usuario := 20; impuesto := subtotal * 0.15;
SELECT INTO
El resultado de un comando SELECT que produce columnas mltiples (pero slo un rengln) puede ser asignado a una variable registro, variable tipo-rengln o una lista de variables escalares. Esto se realiza con: SELECT INTO meta expresiones_select FROM ...; en donde meta puede ser una variable registro, una variable rengln o una lista de variables simples y campos registro/rengln separados por comas. Las expresiones_select y el resto del comando son iguales que en el SQL regular. Observe que es muy diferente de la interpretacin normal de SELECT INTO de PostgreSQL, en donde la meta INTO es una tabla recin creada. Si desea crear una tabla a partir de una resultado de un SELECT dentro de una funcin PL/pgSQL, use la sintaxis CREATE TABLE ... AS SELECT. Si un rengln o una lista de variables se usa como meta, los valores seleccionados deben coincidir exactamente con la estructura de la meta, u ocurrir un error en tiempo de ejecucin. Cuando la meta es una variable registro, automticamente se configura siguiendo la estructura del tipo rengln de la columnas del resultado de la consulta. Las sentencia SELECT es la misma que el comando SELECT normal y puede utilizarse con todo su poder, con la excepcin de la clasula INTO. La clasula INTO puede aparecer casi en cualquier lugar en la sentencia SELECT. Suele escribirse ya sea antes de SELECT como se muestra arriba o justo antes de FROM es decir, justo antes o justo despus de la lista de las expresiones_select. Si la consulta regresa cero renglones, se asignan valores nulos a la(s) meta(s). Si la consulta regresa mltiples renglones, se asigna el primer 10
rengln a la(s) meta(s) y el resto se descarta. (Observe que el primer rengln no est bien definido a menos que haga uso de ORDER BY). Puede verificar la variable especial FOUND (vea la seccin de nombre Obteniendo el Estado del Resultado) despus de una sentencia SELECT INTO para determinar si la Asignacin fue correcta, es decir, que la consulta regres al menos un rengln. Por ejemplo: SELECT INTO mireg * FROM emp WHERE empnombre= minombre; IF NOT FOUND THEN RAISE EXCEPTION no se encontr al empleado %, minombre; END IF; Para probar si un resultado registro/rengln es nulo puede usar la condicional IS NULL. Sin embargo, no existe una manera de decir si han sido descartados algunos renglones adicionales. Aqu hay un ejemplo que maneja el caso en que no se han regresado renglones: DECLARE reg_usuarios RECORD; BEGIN SELECT INTO reg_usuarios * FROM usuarios WHERE id_usuario=3; IF reg_usuarios.homepage IS NULL THEN -- El usuario no digit un homepage, regresar "http://" RETURN http://; END IF; END;
12
Este ejemplo ilustra el uso de las funciones quote_ident(text) y quote_literal(text). Por seguridad, las variables que contienen valores que deben ser cadenas literales en el comando construido deben pasarse a quote_literal. Ambas siguen los pasos apropiados para regresar el texto de entrada encerrado en comillas sencillas o dobles respectivamente, con cualquier carcter especial embebido escapado de la manera correcta. Observe que el entrecomillado con el smbolo de dlares es til solamente para entrecomillar texto fijo. Sera muy mala idea el tratar de hacer el ejemplo anterior como: EXECUTE UPDATE tbl SET || quote_ident(nombrecol) || = $$ || nuevovalor || $$ WHERE llave= || quote_literal(llavevalor); Debido a que podra fallar si el contenido de nuevo valor contiene $$. La misma objecin podra aplicarse a cualquier otro delimitador del tipo dlar que usara. Asi que, para entrecomillar de manera segura el texto que no conozca de inicio, debe usar quote_literal.
Estructuras de Control
Las estructuras de control son probablemente la parte ms til (e importante) de PL/pgSQL. Con las estructuras de control de PL/pgSQL puede manipular los datos de PostgreSQL de una manera flexible y poderosa. Regreso de una Funcin existen dos comandos que le permiten regresar datos desde una funcin: RETURN Y RETURN NEXT.
13
RETURN RETURN expresin; RETURN con una expresin termina la funcin y regresa el valor de expresin a quin la est llamando. Esta forma debe ser usada para las funciones PL/pgSQL que no regresan un conjunto. Cuando se regresa un tipo escalar puede usarse cualquier expresin. El resultado de la expresin ser transformado (cast) automticamente al tipo de retorno de la funcin, tal como se defini en la asignacin. Para regresar un valor compuesto (rengln) debe escribir una variable registro o rengln como la expresin. El valor de retorno de una funcin no puede quedarse indefinido. Si el control alcanza el final de bloque ms externo de la funcin sin encontrar una sentencia RETURN, se producir un error en tiempo de ejecucin. Si declar que la funcin regrese void, tambin debe proporcionar una sentencia RETURN, pero en este caso la expresin que sigue a RETURN ser opcional y ser ignorada si est presente. RETURN NEXT RETURN NEXT expresin; Cuando se declara que una funcin PL/pgSQL regrese SETOF algn tipo, el procedimiento a seguir es ligeramente diferente. En este caso, los items individuales a retornar se especifican en comandos RETURN NEXT, y despus un comando final RETURN sin argumentos se utiliza para indicar que la funcin ha terminado de ejecutarse. RETURN NEXT puede usarse con tipos escalares y compuestos; en el ltimo caso, sera regresado una tabla completa de resultados. Las funciones que usan RETURN NEXT deben se llamadas de la siguiente manera: SELECT * FROM alguna_func(); Es decir, las funciones deben se usadas como una tabla fuente en una clusula FROM. RETURN NEXT realmente no regresa de la funcin, simplemente almacena el valor de la expresin. Despus, contina la ejecucin de la siguiente sentencia en la funcin PL/pgSQL. Al ejecutarse los comandos sucesivos RETURN NEXT, se va armando el resultado. Un RETURN final, sin argumentos, ocasiona que el control salga de la funcin. La implementacin actual de RETURN NEXT para PL/pgSQL almacena el conjunto resultante completo antes de regresar de la funcin, como es explica arriba. Esto significa que si una funcin PL/pgSQL produce un conjunto resultante muy grande, el desempeo puede empobrecerse: los datos sern escritos en el disco para evitar el consumo de memoria, pero la funcin misma no regresar hasta que todo el conjunto resultante haya sido generado. Una versin futura de PL/pgSQL puede permitir a los usuarios el definir funciones que regresen conjuntos que no tengan esa limitante. Por lo pronto, el momento en que los datos empiezan a escribirse en el disco es controlado por la variable de configuracin work_mem. Los administradores que cuenten con suficiente memoria para almacenar conjuntos resultantes ms grandes en la memoria, deben considerar el aumentar este parmetro.
14
Condicionales
Las sentencias IF le permiten ejecutar comandos cuando se dan ciertas condiciones. PL/pgSQL tiene cinco formas de IF: IF ... THEN IF ... THEN ... ELSE IF ... THEN ... ELSE IF IF ... THEN ... ELSIF ... THEN ... ELSE IF ... THEN ... ELSEIF ... THEN ... ELSE IF-THEN IF expresin-lgica THEN sentencias END IF; Las sentencias IF-THEN son las formas ms simples de IF. Las sentencias entre THEN y END IF sern ejecutadas si la condicin es verdadera. De otra manera, sern ignoradas. Ejemplo: IF v_id_usuario <> 0 THEN UPDATE usuarios SET email = v_email WHERE id_usuario= v_id_usuario; END IF; IF-THEN-ELSE IF expresin-lgica THEN sentencias ELSE sentencias END IF; Las sentencias IF-THEN-ELSE aaden funcionalidad a IF-THEN permitindole especificar un conjunto de sentencias alternativo que debe ejecutarse si la condicin produce un valor de falso. Ejemplo: IF parentid IS NULL OR parentid = THEN RETURN fullname; ELSE RETURN hp_true_filename(parentid) || / || fullname; END IF; IF v_cuenta> 0 THEN INSERT INTO usuarios_cuenta(count) VALUES (v_cuenta); RETURN t; ELSE RETURN f; END IF;
15
IF-THEN-ELSE IF Las sentencias IF pueden anidarse, como se muestra en el siguiente ejemplo: IF demo_renglon.sexo = m THEN pretty_sex := hombre; ELSE IF demo_renglon.sexo = f THEN pretty_sex := mujer; END IF; END IF; IF-THEN-ELSIF-ELSE IF expresin-lgica THEN sentencias [ ELSIF expresin-lgica THEN sentencias [ ELSIF expresin-lgica THEN sentencias ...]] [ ELSE sentencias ] END IF; IF-THEN-ELSIF-ELSE proporciona un mtodo ms conveniente para revisar varias alternativas en una sentencia. Formalmente es equivalente a los comandos anidados. IF-THEN-ELSE-IF-THEN, pero solo se necesita un END IF. A continuacin en ejemplo: IF numero = 0 THEN resultado := cero; ELSIF numero > 0 THEN resultado := positivo; ELSIF numero < 0 THEN resultado := negativo; ELSE -- hmm, la nica otra posibilidad que el nmero sea nulo resultad := NULL; END IF;
16
Ciclos Simples
Con las sentencia LOOP, EXIT, WHILE y FOR, usted puede hacer que en sus funciones PL/pgSQL se repitan una serie de comandos. LOOP [<<etiqueta>>] LOOP Sentencias END LOOP; LOOP define un ciclo incondicional que se repite indefinidamente hasta que encuentra alguna sentencia EXIT o RETURN. La etiqueta opcional puede usarse por las sentencias. EXIT En los ciclos anidados para especificar que nivel de anidamiento debe terminarse. EXIT [ etiqueta ] [ WHEN expresin ]; Si no se proporciona una etiqueta se termina el ciclo ms interno y se ejecuta a continuacin la sentencia posterior a END LOOP. Si se define una etiqueta, sta debe ser la etiqueta del nivel actual o de algn otro ms externo del ciclo anidado o del bloque. Entonces, el ciclo o bloque nombrado se termina y el control contina con la sentencia posterior al END del ciclo/bloque correspondiente. Si WHEN est presente, la salida del ciclo ocurre solo si la condicin especificada es verdadera, de otra manera, el control pasa a la sentencia despus del EXIT. EXIT puede utilizarse para provocar una salida temprana de todo tipo de ciclos; no est limitado al uso de ciclos condicionales. Ejemplos:
LOOP -- algun procesamiento IF count > 0 THEN EXIT; -- salir del ciclo END IF; END LOOP; LOOP -- algn procesamiento EXIT WHEN count > 0; -- mismo resultado que en el ejemplo anterior END LOOP; BEGIN -- algn procesamiento IF stocks > 100000 THEN EXIT; -- causa la salida del bloque BEGIN END IF; END;
17
WHILE [<<etiqueta>>] WHILE expresin LOOP sentencia END LOOP; La sentencia WHILE repite una secuencia de sentencias tanto como la expresin de la condicin produzca un valor de verdadero. La condicin se revisa justo antes de cada entrada al cuerpo del ciclo. Por ejemplo: WHILE cantidad_adeudo > 0 AND balance_certificado_regalo > 0 LOOP -- algn procesamiento END LOOP; WHILE NOT expresin_lgica LOOP -- algn procesamiento END LOOP; FOR (variante con enteros) [<<etiqueta>>] FOR nombre IN [ REVERSE ] expresin .. expresin LOOP sentencias END LOOP; Esta forma de FOR crea un ciclo que itera sobre un rango de valores enteros. La variable nombre se define de manera automtica como de tipo integer y existe solo dentro del ciclo. Las dos expresiones que generan los lmites inferiores y superior del rango, son evaluados una sola vez al entrar al ciclo. El paso de la iteracin es 1 generalmente, pero es -1 cuando se especifica REVERSE. Algunos ejemplos de ciclos enteros FOR: FOR i IN 1..10 LOOP -- algn procesamiento aqu RAISE NOTICE i es %, i; END LOOP; FOR i IN REVERSE 10..1 LOOP -- algn procesamiento aqu END LOOP;
18