Sentencia compuesta
Una sentencia compuesta agrupa otras sentencias en una rutina SQL o un disparador avanzado.
Una instrucción compuesta permite la declaración de variables SQL, cursores y controladores de condiciones.
Sintaxis
Declaración de variable SQL:
Declaración de condición SQL:
declaración-de-códigos-de-devolución:
declaración:
manejador-declaración:
valor-de-condición-específica:
general-condition-value:
Descripción
- etiqueta
- Especifica la etiqueta para la instrucción compuesta. Si se especifica la etiqueta inicial, puede utilizarse para calificar variables SQL declaradas en la sentencia compuesta y también puede especificarse como destino en una sentencia LEAVE. Si se especifica la etiqueta final, debe ser la misma que la etiqueta inicial.
El nombre de la etiqueta no puede ser el mismo que el nombre de la rutina, el nombre del desencadenante u otra etiqueta dentro del mismo ámbito.
ATOMIC or NOT ATOMIC
FL 500 Especifica si una condición de excepción no controlada dentro de una sentencia compuesta hace que dicha sentencia compuesta se revierta. El valor predeterminado para la sentencia compuesta más externa en un disparador avanzado es ATOMIC; de lo contrario, el valor predeterminado es NOT ATOMIC.- ATOMIC
- ATOMIC indica que una condición de excepción no gestionada dentro de la sentencia compuesta hace que la sentencia compuesta se revierta. ATOMIC no debe especificarse en una sentencia compuesta en una función escalar SQL, en un procedimiento SQL o en una sentencia compuesta que esté anidada dentro de otra sentencia compuesta que esté definida como ATOMIC.
- NOT ATOMIC
- NOT ATOMIC indica que una condición de excepción no gestionada dentro de la sentencia compuesta no provoca que la sentencia compuesta se revierta. NOT ATOMIC no debe especificarse en la declaración compuesta más externa de un desencadenador avanzado.

- declaración-variable-SQL
- Declara una variable que es local respecto a la sentencia compuesta.
- Nombre de variable SQL
- Define el nombre de una variable. Db2 convierte todos los nombres de variables SBCS SQL que no están delimitados a mayúsculas. El nombre de la variable SQL debe ser único dentro de la sentencia compuesta en la que se declara, excluyendo cualquier declaración en sentencias compuestas que estén anidadas dentro de esa sentencia compuesta. El nombre de la variable SQL no debe ser el mismo que el nombre de un parámetro. Consulte Referencias a parámetros y variables SQL en SQL PL para obtener información sobre cómo se resuelven los nombres de variables SQL cuando hay columnas con el mismo nombre que una variable SQL involucrada en una instrucción, o cuando existen múltiples variables SQL con el mismo nombre en el cuerpo de la rutina.
Solo se puede hacer referencia a SQL-variable-name dentro de la sentencia compuesta en la que se declara, incluida cualquier sentencia compuesta que esté anidada dentro de esa sentencia compuesta. Si la sentencia compuesta donde se declara la variable tiene una etiqueta, las referencias al nombre de la variable pueden calificarse con esa etiqueta. Por ejemplo, una variable SQL V que se declara en una sentencia compuesta etiquetada como C puede referenciarse como C.V.
- tipo-datos
- Especifica el tipo de datos y la longitud de la variable. Las variables SQL siguen las mismas reglas de longitud predeterminada y máxima que los parámetros de rutina SQL. Consulte la declaración CREATE FUNCTION (función escalar SQL compilada ) para obtener descripciones de los tipos de datos y longitudes de SQL.
DEFAULT o CONSTANT
FL 500 Especifica un valor para la variable SQL cuando se introduce la instrucción compuesta en la que se declara. Si no se especifica ni DEFAULT ni CONSTANT, el valor predeterminado para la variable SQL es el valor nulo. Solo se puede especificar explícitamente DEFAULT NULL si se especifica array-type-name. Solo se puede especificar DEFAULT NULL o CONSTANT NULL para una variable SQL con el tipo de datos XML.- DEFAULT
- Define el valor predeterminado de la variable de SQL. La constante especificada debe representar un valor que pueda asignarse a la variable de acuerdo con las reglas de asignación descritas en Asignación y comparación.
- CONSTANT
- Especifica que la variable de SQL tiene un valor fijo que no se puede cambiar. Una variable de SQL que se defina mediante CONSTANT no puede utilizarse como destino de una operación de asignación. La constante especificada debe representar un valor que pueda asignarse a la variable de acuerdo con las reglas de asignación descritas en Asignación y comparación.
Las variables que se denominan SQLCODE y SQLSTATE no se pueden definir utilizando CONSTANT.
- Nulo
- Especifica NULL como un valor predeterminado para la variable de SQL.
- Constante
- Especifica una constante como un valor predeterminado para la variable de SQL.

- RESULT_SET_LOCATOR VARYING
- Especifica el tipo de datos de una variable localizadora de conjuntos de resultados.
- Declaración de condición SQL
- Declara el nombre de una condición y el valor SQLSTATE asociado.
- SQL-nombre-condición
- Especifica el nombre de la condición. El nombre de la condición debe ser único dentro de la sentencia compuesta en la que se declara, excluyendo cualquier declaración que se encuentre en sentencias compuestas anidadas dentro de esa sentencia compuesta. Sólo se puede hacer referencia al nombre de una condición dentro de la sentencia compuesta en la que está declarada, incluidas las sentencias compuestas anidadas dentro de dicha sentencia compuesta.
- FOR SQLSTATE cadena-constante
- Especifica el SQLSTATE que está asociado a la condición. La cadena debe especificarse como cinco caracteres entre comillas simples, y la clase SQLSTATE (los dos primeros caracteres) no debe ser '00'.
- declaración-códigos-retorno
- Declara variables especiales llamadas SQLSTATE y SQLCODE. Estas variables se establecen automáticamente en los valores SQLSTATE y SQLCODE para la primera condición en el área de diagnóstico después de ejecutar una instrucción SQL que no sea GET DIAGNOSTICS o una instrucción compuesta vacía.
Las variables SQL SQLSTATE y SQLCODE solo están pensadas para ser utilizadas como medio para obtener los códigos de retorno SQL que resultaron del procesamiento de la instrucción SQL anterior que no sea GET DIAGNOSTICS. Si existe la intención de utilizar los valores SQLSTATE y SQLCODE, guárdelos inmediatamente en otras variables SQL para evitar que los valores sean reemplazados por los códigos de retorno SQL devueltos después de ejecutar la siguiente sentencia SQL. Si se define un controlador que maneja un SQLSTATE, puede utilizar una instrucción de asignación para guardar ese valor SQLSTATE (o el SQLCODE asociado) en otra variable SQL, si la asignación es la primera instrucción en el controlador.
La asignación a estas variables no está prohibida; sin embargo, no se recomienda. Los controladores de condiciones ignoran la asignación a estas variables, y el procesamiento de una asignación a estas variables especiales hace que los valores especificados para la asignación se superpongan con los códigos de retorno SQL devueltos de la ejecución de la sentencia que realiza la asignación. Las variables SQL SQLSTATE y SQLCODE no se pueden establecer en NULL.
- declaración-sentencia
- Declara una lista de uno o más nombres que son locales en la sentencia compuesta. Un nombre de declaración no puede ser el mismo que otro nombre de declaración dentro de la misma declaración compuesta.
- sentencia-declare-cursor
- Declara un cursor en el cuerpo del procedimiento. Cada cursor debe tener un nombre único dentro de la rutina. Solo se puede hacer referencia al cursor desde dentro de la sentencia compuesta en la que se declara, incluidas las sentencias compuestas anidadas dentro de esa sentencia compuesta. Utilice una instrucción OPEN para abrir el cursor, una instrucción FETCH para leer una fila utilizando el cursor y una instrucción CLOSE para cerrar el cursor. Si el cursor está destinado a ser utilizado como cursor de conjunto de resultados:
- Especifique CON DEVOLUCIÓN cuando se declare el cursor
- Cree el procedimiento utilizando la cláusula DYNAMIC RESULT SETS con un valor distinto de cero
- No especifique una sentencia CLOSE para el cursor en la sentencia compuesta
- declaración-manejador
- Especifica un controlador de condición, una instrucción de procedimiento SQL que se ejecuta cuando se produce una excepción o condición de finalización en la instrucción compuesta. La instrucción de procedimiento SQL se ejecuta cuando un controlador de condiciones recibe el control.
Una declaración de controlador de condición no puede hacer referencia al mismo valor de condición o valor SQLSTATE más de una vez. No puede hacer referencia a un valor SQLSTATE y a un nombre de condición que representen el mismo valor SQLSTATE.
Cuando se declaran dos o más gestores de condiciones en una sentencia compuesta, no pueden especificar lo mismo dos declaraciones de gestores de condiciones:
- categoría de condición general
- condición específica, ya sea como un valor SQLSTATE o como un nombre de condición que represente el mismo valor
Un controlador de condiciones está activo para el conjunto de sentencias de procedimiento SQL que siguen a las declaraciones del controlador de condiciones dentro de la sentencia compuesta en la que se declara el controlador de condiciones, incluidas las sentencias compuestas anidadas.
- CONTINUE
- Especifica que después de que el controlador de condiciones se active y se complete con éxito, el control se devuelve a la instrucción SQL que sigue a la instrucción que activó la condición. Sin embargo, si la condición es una condición de error y se encontró mientras se evaluaba una condición de búsqueda, como en una declaración CASE, FOR, IF, REPEAT o WHILE, el control vuelve a la declaración que sigue a la correspondiente END CASE, END FOR, END IF, END REPEAT o END WHILE.
- EXIT
- Especifica que, después de que el controlador de condiciones se active y se complete correctamente, el control se devuelve al final de la sentencia compuesta que declaró el controlador de condiciones.
Las condiciones que pueden hacer que el controlador obtenga el control son:
- SQLSTATE cadena-constante
- Especifica que el controlador se invoca cuando se produce el SQLSTATE específico. Los dos primeros caracteres del valor SQLSTATE no deben ser '00'.
- SQL-nombre-condición
- Especifica que el controlador se invoca cuando se produce el SQLSTATE específico asociado con el nombre de la condición. El nombre de la condición SQL debe declararse dentro de la sentencia compuesta que contiene las declaraciones del controlador, o dentro de una sentencia compuesta en la que esa sentencia compuesta esté anidada.
- SQLEXCEPTION
- Especifica que el controlador se invoca cuando se produce una SQLEXCEPTION. Un SQLEXCEPTION es un SQLSTATE en el que el código de clase es un valor distinto de '00', '01' o '02'. Para obtener más información sobre los valores SQLSTATE, consulte Valores SQLSTATE y códigos de error comunes.
- SQLWARNING
- Especifica que el controlador se invoca cuando se produce un SQLWARNING. Un SQLWARNING es un valor SQLSTATE con un código de clase de «01».
- NOT FOUND
- Especifica que el manejador de condiciones se invoca cuando se produce una condición de "no encontrado" (NOT FOUND). NOT FOUND corresponde a un valor SQLSTATE con un código de clase de '02'.
Notas
A diferencia de las variables de host, las variables SQL no van precedidas de dos puntos cuando se utilizan en sentencias SQL.
Anidación de sentencias compuestas : Las sentencias compuestas pueden anidarse. Las sentencias compuestas anidadas pueden utilizarse para delimitar las definiciones de variables, los nombres de condiciones, los controladores de condiciones y los cursores a un subconjunto de las sentencias de una rutina. Esto puede simplificar el procesamiento que se realiza para cada instrucción de rutina SQL. Las sentencias compuestas anidadas permiten el uso de una sentencia compuesta dentro de la declaración de un controlador de condición.
El ámbito de un cursor : El ámbito de un nombre de cursor es la sentencia compuesta en la que se declara, incluidas las sentencias compuestas anidadas dentro de esa sentencia compuesta. Sólo se puede hacer referencia al nombre de un cursor dentro de la sentencia compuesta en la que está declarado, incluidas las sentencias compuestas anidadas dentro de dicha sentencia compuesta.
Consideraciones para el nombre de la sentencia : El ámbito de un nombre de sentencia que se declara en una sentencia compuesta es la sentencia compuesta y cualquier sentencia compuesta anidada (a menos que el mismo nombre de sentencia se declare en una sentencia compuesta anidada). Si se utiliza un nombre de sentencia en una sentencia DECLARE CURSOR o en una sentencia PREPARE y no se ha declarado en la sentencia compuesta donde se utiliza o en ninguna sentencia compuesta externa en la que esté anidada, se asume que el nombre de la sentencia se declara globalmente para la rutina.
Encargados de la condición:
Los controladores de condiciones en las rutinas SQL y los desencadenadores avanzados son similares a las sentencias WHENEVER que se utilizan en los programas de aplicaciones SQL externas. Se puede definir un controlador de condiciones para obtener automáticamente el control cuando se produce una excepción, una advertencia o una condición de no encontrado. El cuerpo de un controlador de condiciones contiene código que se ejecuta cuando se activa el controlador de condiciones. Un controlador de condiciones puede activarse como resultado de una excepción, una advertencia o una condición no encontrada que devuelve Db2 para el procesamiento de una instrucción SQL. O la condición que activa el controlador puede ser el resultado de una instrucción SIGNAL o RESIGNAL que se emite dentro de la rutina SQL o del cuerpo del desencadenador.
Un controlador de condiciones se declara dentro de una sentencia compuesta y está activo para el conjunto de sentencias de procedimiento SQL que siguen a todas las declaraciones de controladores de condiciones dentro de la sentencia compuesta en la que se declara el controlador de condiciones. Por ejemplo, el alcance de una declaración de controlador de condición H es la lista de sentencias de procedimiento SQL que siguen a las declaraciones de controlador de condición que están contenidas dentro de la sentencia compuesta en la que aparece H. Esto significa que el ámbito de H no incluye las declaraciones que están contenidas en el cuerpo del controlador de condiciones H, lo que implica que un controlador de condiciones no puede manejar condiciones que surjan dentro de su propio cuerpo. Del mismo modo, para cualquier par de gestores de condiciones H1 y H2 que se declaren en la misma sentencia compuesta, H1 no gestionará las condiciones que surjan en el cuerpo de H2, y H2 no gestionará las condiciones que surjan en el cuerpo de H1.
La declaración de un controlador de condición especifica la condición que lo activa, el tipo de controlador de condición (CONTINUAR o SALIR) y la acción del controlador. El tipo de controlador de condición determina a dónde se devuelve el control después de que la acción del controlador se complete con éxito.
Activación del controlador de condiciones : Cuando se produce una condición distinta de la finalización con éxito en el procesamiento de la instrucción de procedimiento SQL, si un controlador de condiciones que podría manejar la condición está dentro del alcance, se activará uno de esos controladores de condiciones para procesar la condición.
En una rutina con sentencias compuestas anidadas, los controladores de condiciones que podrían manejar una condición específica podrían existir en varios niveles de las sentencias compuestas anidadas. El controlador de condiciones que se activa es el que se declara más interno al ámbito en el que se encontró la condición. Si más de un controlador de condiciones en el nivel de anidamiento pudiera manejar la condición, el controlador de condiciones que se activa es el controlador más apropiado que se declara en esa sentencia compuesta.
El controlador más apropiado es el controlador de condición que más se asemeja al SQLSTATE o a la excepción o condición de finalización. Para una instrucción compuesta determinada, cuando se declaran tanto un controlador específico para una condición como un controlador general que abordan la misma condición, el controlador específico tiene prioridad sobre el controlador general.
Por ejemplo, si la sentencia compuesta más interna declara un controlador específico para SQLSTATE '22001', así como un controlador general para SQLEXCEPTION, el controlador específico para SQLSTATE '22001' es el controlador más apropiado cuando se encuentra SQLSTATE '22001'. En este caso, se activa el controlador específico.
Cuando se activa un controlador de condiciones, se ejecuta la acción del controlador de condiciones. Si la acción del controlador se completa correctamente o con una advertencia no manejada, el área de diagnóstico se borra y el tipo de controlador de condición (CONTINUE o EXIT) determina a dónde se devuelve el control. Además, las variables SQL SQLSTATE y SQLCODE se borran cuando un controlador se completa correctamente o con una advertencia no controlada.
Si la acción del controlador no se completa correctamente y existe un controlador apropiado para la condición que se encuentra en la acción del controlador, se activa ese controlador de condición. De lo contrario, la condición que se encuentra dentro del controlador de condiciones no se gestiona.
Condiciones no gestionadas : si se encuentra una condición y no existe un gestor adecuado para esa condición, la condición no se gestiona.
Si la condición no controlada es una excepción, la rutina SQL o el desencadenador avanzado que contiene la instrucción defectuosa finaliza con una condición de excepción no controlada.
- Si la condición no resuelta es una advertencia o no se encuentra, el procesamiento continúa con la siguiente instrucción. Tenga en cuenta que el procesamiento de la siguiente instrucción SQL provocará que la información sobre la condición no gestionada en el área de diagnóstico se sobrescriba, y que la evidencia de la condición no gestionada ya no existirá.
Si una rutina SQL o un desencadenador avanzado finaliza con una advertencia no gestionada o una condición no encontrada, la condición se devuelve a la instrucción de invocación. Si un desencadenante básico finaliza con una advertencia no gestionada o una condición no encontrada, la condición no se devuelve a la instrucción de invocación.
Consideraciones para el uso de sentencias SIGNAL y RESIGNAL con sentencias compuestas anidadas : Si una sentencia de procedimiento SQL que se especifica en el controlador de condiciones es una sentencia SIGNAL o RESIGNAL con una excepción SQLSTATE, la sentencia compuesta termina con la excepción especificada. Esto ocurre incluso cuando este controlador de condiciones u otro controlador de condiciones en la misma sentencia compuesta especifica CONTINUAR, ya que estos controladores de condiciones no están en el ámbito de esta excepción. Si una sentencia compuesta está anidada en otra sentencia compuesta, los controladores de condiciones de la sentencia compuesta de nivel superior pueden gestionar la excepción porque esos controladores de condiciones están dentro del ámbito de la excepción.
Variables SQLSTATE y SQLCODE en rutinas SQL y activadores avanzados : para ayudar a depurar sus rutinas SQL y activadores avanzados, puede resultarle útil comprobar el valor de SQLSTATE y SQLCODE después de ejecutar una instrucción. Una variable SQLCODE o SQLSTATE puede ser declarada y posteriormente referenciada en una rutina SQL o un disparador avanzado. Podría insertar el valor de SQLCODE y SQLSTATE en una tabla en varios puntos de la rutina SQL o del activador avanzado, o devolver los valores SQLCODE y SQLSTATE en una cadena de diagnóstico como parámetro OUT para un procedimiento SQL. Para utilizar los valores SQLCODE y SQLSTATE, debe declarar las siguientes variables SQL en la rutina SQL o en el cuerpo del activador avanzado: 
Cuando se hace referencia a las variables SQLCODE o SQLSTATE en una rutina SQL o un desencadenador avanzado, Db2 establece el valor de SQLCODE en 0 y SQLSTATE en '00000' para la instrucción posterior. También puede utilizar controladores de condición CONTINUE para asignar el valor de las variables SQLSTATE y SQLCODE a variables en su rutina SQL o cuerpo de activador avanzado. A continuación, puede utilizar estas variables SQL para controlar su lógica de rutina o activación, o devolver el valor como parámetro de salida. En el siguiente ejemplo, la rutina SQL devuelve el control a la instrucción que sigue a cada instrucción SQL con el SQLCODE establecido en una variable SQL llamada RETCODE: 
DECLARE SQLCODE INTEGER DEFAULT 0;
DECLARE retcode INTEGER DEFAULT 0;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET retcode = SQLCODE;
DECLARE CONTINUE HANDLER FOR SQLWARNING SET retcode = SQLCODE;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET retcode = SQLCODE;La sentencia compuesta en sí misma no afecta a las variables SQL SQLSTATE y SQLCODE. Sin embargo, las sentencias SQL contenidas dentro de la sentencia compuesta pueden afectar a las variables SQL SQLSTATE y SQLCODE. Al final de la sentencia compuesta, las variables SQL SQLSTATE y SQLCODE reflejan el resultado de la última sentencia SQL ejecutada dentro de la sentencia compuesta que provocó un cambio en las variables SQL SQLSTATE y SQLCODE. Si las variables SQL SQLSTATE y SQLCODE no se modificaron dentro de la sentencia compuesta, contienen los mismos valores que cuando se introdujo la sentencia compuesta.
Valores nulos en parámetros SQL y variables SQL : Si el valor de un parámetro SQL o variable SQL es nulo y se utiliza en una instrucción SQL que no permite una variable indicadora, se devuelve un error.
Efecto en los cursores abiertos : Al final de la sentencia compuesta, se cierran todos los cursores abiertos que se declaran en dicha sentencia compuesta, excepto los cursores que se utilizan para devolver conjuntos de resultados.
Procesamiento atómico de una sentencia compuesta : El procesamiento atómico no es compatible con una sentencia compuesta. Si se necesita un comportamiento atómico para un bloque de código en una sentencia compuesta, establezca un punto de guardado antes de introducir la sentencia compuesta anidada. Esto permitirá deshacer los cambios con una instrucción ROLLBACK TO SAVEPOINT.
ejemplos
Ejemplo 1 : Cree un cuerpo de procedimiento con una sentencia compuesta que realice las siguientes acciones:
- Declara variables SQL.
- Declara un cursor para que proporcione el salario de los empleados de un departamento determinado de acuerdo con un parámetro IN.
- Declara un controlador EXIT para la condición NOT FOUND (fin de archivo). La instrucción de procedimiento SQL del controlador asigna el valor 6666 al parámetro OUT medianSalary.
- Selecciona el número de empleados en el departamento dado en la variable SQL v_numRecords.
- Recupera filas desde el cursor en un bucle WHILE hasta que se hayan recuperado los registros de salario del 50 % + 1 de los empleados del departamento.
- Devuelve el salario medio.
CREATE PROCEDURE DEPT_MEDIAN
(IN deptNumber SMALLINT,
OUT medianSalary DOUBLE)
LANGUAGE SQL
BEGIN
DECLARE v_numRecords INTEGER DEFAULT 1;
DECLARE v_counter INTEGER DEFAULT 0;
DECLARE c1 CURSOR FOR
SELECT salary FROM staff
WHERE DEPT = deptNumber
ORDER BY salary;
DECLARE EXIT HANDLER FOR NOT FOUND
SET medianSalary = 6666;
/* initialize OUT parameter */
SET medianSalary = 0;
SELECT COUNT(*) INTO v_numRecords FROM staff
WHERE DEPT = deptNumber;
OPEN c1;
WHILE v_counter < (v_numRecords / 2 + 1) DO
FETCH c1 INTO medianSalary;
SET v_counter = v_counter + 1;
END WHILE;
CLOSE c1;
END
Ejemplo 2 : Definir un controlador de salida para cualquier error, advertencia o caso de fin de datos. Cuando este procedimiento se invoca correctamente, se devuelve el valor 45000 para el parámetro de salida:CREATE PROCEDURE JMBLIB.PROCL(OUT MEDIANSALARY INT)
LANGUAGE SQL
BEGIN
DECLARE CHAR1 CHAR;
DECLARE C1 CURSOR FOR SELECT *
FROM SYSIBM.SYSDUMMY1;
DECLARE EXIT HANDLER FOR NOT FOUND,
SQLEXCEPTION,
SQLWARNING
RETURN;
OPEN C1;
FETCH C1 INTO CHAR1;
SET MEDIANSALARY = 45000;
FETCH C1 INTO CHAR1;
SET MEDIANSALARY = 50000;
END
