La sentencia BEGIN ...END proporciona a las sentencias definidas en las palabras clave BEGIN y END el estado de una sentencia individual.
La etiqueta sólo puede aparecer por segunda vez si existe una primera etiqueta. Si aparecen ambas etiquetas, éstas deben ser idénticas. Dos o más sentencias con etiqueta en el mismo nivel pueden tener la misma etiqueta, pero esto anula en parte la ventaja de la segunda etiqueta. La ventaja es que las etiquetas hacen que cada END, coincida de forma exacta y sin ambigüedades, con su BEGIN. No obstante, una sentencia que contiene una etiqueta anidada dentro de Sentencias no puede tener la misma etiqueta porque esto hace que el comportamiento de las sentencias ITERATE y LEAVE sea ambiguo.
DECLARE Variable1 CHAR 'Existing variable'; -- Un referencia a Variable1 devuelve 'Existing variable' BEGIN -- Un referencia a Variable1 devuelve 'Existing variable' DECLARE Variable1 CHAR 'Local variable'; -- Está permitido aunque el nombre sea el mismo -- Un referencia a Variable1 devuelve 'Local variable' END;
Si se especifica ATOMIC, sólo se permite una instancia de un flujo de mensajes (es decir, una hebra) para ejecutar las sentencias de una sentencia BEGIN ATOMIC... END específica (identificada por su esquema y su etiqueta), en un momento dado. Si no hay ninguna etiqueta, el comportamiento es como si se hubiera especificado una etiqueta de longitud cero.
CREATE PROCEDURE WtiteSharedVariable1(IN NewValue CHARACTER) SharedVariableMutex1 : BEGIN ATOMIC -- Establecer el nuevo valor en la variable compartida END; CREATE FUNCTION ReadSharedVariable1() RETURNS CHARACTER SharedVariableMutex1 : BEGIN ATOMIC DECLARE Value CHARACTER; -- Obtener valor de la variable compartida RETURN Value; END;
No anide sentencias BEGIN ATOMIC... END, tanto directa como indirectamente, porque podría originar "inclusiones erróneas". Por ello, no utilice una sentencia PROPAGATE desde dentro de un bloque ATOMIC.
No es necesario utilizar la construcción BEGIN ATOMIC en flujos que nunca se desplegarán con más de una instancia (pero no es aconsejable dejar esto al azar). También es innecesario utilizar la construcción BEGIN ATOMIC en lecturas y grabaciones en variables compartidas. El intermediario siempre graba de forma segura un nuevo valor en una variable compartida, y también de forma segura lee el último valor de esa variable. ATOMIC sólo es necesario cuando la aplicación puede ver resultados intermedios.
DECLARE LastOrderDate SHARED DATE; ... SET LastOrderDate = CURRENT_DATE; ... SET OutputRoot.XMLNSC.Data.Orders.Order[1].Date = LastOrderDate;En este ejemplo suponemos que una hebra actualiza periódicamente LastOrderDate y otra lee periódicamente de ella. No es necesario utilizar ATOMIC, porque la segunda sentencia SET siempre lee un valor válido. Si la actualización y la lectura se realizan dentro de un intervalo de tiempo muy corto, no está definido si se lee el valor antiguo o el nuevo, pero siempre será uno o el otro. El resultado nunca será información no válida.
DECLARE Count SHARED INT; ... SET Count = Count + 1;Aquí suponemos que hay varias hebras ejecutando periódicamente la sentencia SET. En este caso sí es necesario utilizar ATOMIC, porque es posible que dos hebras lean Count casi en el mismo instante, y obtengan el mismo valor. Ambas hebras realizan la adición y ambas almacenan el mismo valor de vuelta. Por tanto, el resultado final es N+1 y no N+2.
El intermediario no proporciona automáticamente ningún bloqueo de nivel superior a éste (por ejemplo, un bloqueo que cubra toda la sentencia SET), porque un bloqueo de este tipo podría originar "inclusiones erróneas".
Puede considerar la sentencia BEGIN ... END como una construcción de bucle que siempre crea un solo bucle. Entonces, el efecto de una sentencia ITERATE o LEAVE anidada dentro de una sentencia BEGIN ... END es el que se espera: el control se transfiere a la sentencia que hay después de END. Utilizar ITERATE o LEAVE en una sentencia BEGIN ... END resulta práctico en los casos en los que hay una larga serie de cálculos que se han de abandonar ya sea porque se ha obtenido un resultado definitivo o porque se ha producido un error.