Estructuras de control en Transact SQL
Estructura condicional IF
La estuctura condicional IF permite evaluar una expresion booleana (resultado SI - NO), y ejecutar las operaciones contenidas en el bloque formado por BEGIN END.
IF (<expresion>) BEGIN ... END ELSE IF (<expresion>) BEGIN ... END ELSE BEGIN ... END
|
Ejemplo de la estructura condicional IF.
DECLARE @Web varchar(100), @diminutivo varchar(3) SET @diminutivo = 'DJK' IF @diminutivo = 'DJK' BEGIN PRINT 'www.devjoker.com' END ELSE BEGIN PRINT 'Otra Web (peor!)' END
|
La estructura IF admite el uso de subconsultas:
DECLARE @coPais int, @descripcion varchar(255) set @coPais = 5 set @descripcion = 'España'
IF EXISTS(SELECT * FROM PAISES WHERE CO_PAIS = @coPais) BEGIN UPDATE PAISES SET DESCRIPCION = @descripcion WHERE CO_PAIS = @coPais END
ELSE BEGIN INSERT INTO PAISES (CO_PAIS, DESCRIPCION) VALUES (@coPais, @descripcion) END
|
Estructura condicional CASE
La estructura condicional CASE permite evaluar una expresion y devolver un valor u otro.
La sintaxis general de case es:
CASE <expresion> WHEN <valor_expresion> THEN <valor_devuelto> WHEN <valor_expresion> THEN <valor_devuelto> ELSE <valor_devuelto> -- Valor por defecto END
|
Ejemplo de CASE.
DECLARE @Web varchar(100), @diminutivo varchar(3)
SET @diminutivo = 'DJK' SET @Web = (CASE @diminutivo WHEN 'DJK' THEN 'www.devjoker.com' WHEN 'ALM' THEN 'www.aleamedia.com' ELSE 'www.devjoker.com' END) PRINT @Web |
Otra sintaxis de CASE nos permite evaluar diferentes expresiones:
CASE WHEN <expresion> = <valor_expresion> THEN <valor_devuelto> WHEN <expresion> = <valor_expresion> THEN <valor_devuelto> ELSE <valor_devuelto> -- Valor por defecto
END
|
El mismo ejemplo aplicando esta sintaxis:
DECLARE @Web varchar(100), @diminutivo varchar(3) SET @diminutivo = 'DJK' SET @Web = (CASE WHEN @diminutivo = 'DJK' THEN 'www.devjoker.com' WHEN @diminutivo = 'ALM' THEN 'www.aleamedia.com' ELSE 'www.devjoker.com' END) PRINT @Web
|
Otro aspecto muy interesante de CASE es que permite el uso de subconsultas.
DECLARE @Web varchar(100), @diminutivo varchar(3) SET @diminutivo = 'DJK' SET @Web = (CASE WHEN @diminutivo = 'DJK' THEN (SELECT web FROM WEBS WHERE id=1) WHEN @diminutivo = 'ALM' THEN (SELECT web FROM WEBS WHERE id=2) ELSE 'www.devjoker.com' END) PRINT @Web
|
Bucle WHILE
El bucle WHILE se repite mientras expresion se evalue como verdadero.
Es el único tipo de bucle del que dispone Transact SQL.
WHILE <expresion> BEGIN ... END
|
Un ejemplo del bucle WHILE.
DECLARE @contador int SET @contador = 0 WHILE (@contador < 100) BEGIN SET @contador = @contador + 1
PRINT 'Iteracion del bucle ' + cast(@contador AS varchar) END
|
Podemos pasar a la siguiente iteración del bucle utilizando CONTINUE.
DECLARE @contador int SET @contador = 0 WHILE (@contador < 100) BEGIN SET @contador = @contador + 1 IF (@contador % 2 = 0) CONTINUE PRINT 'Iteracion del bucle ' + cast(@contador AS varchar) END
|
El bucle se dejará de repetir con la instrucción BREAK.
DECLARE @contador int SET @contador = 0 WHILE (1 = 1) BEGIN SET @contador = @contador + 1 IF (@contador % 50 = 0) BREAK PRINT 'Iteracion del bucle ' + cast(@contador AS varchar) END
|
También podemos utilizar el bucle WHILE conuntamente con subconsultas.
DECLARE @coRecibo int WHILE EXISTS (SELECT * FROM RECIBOS WHERE PENDIENTE = 'S')-- Ojo, la subconsulta se ejecuta -- una vez por cada iteracion -- del bucle! BEGIN SET @coRecibo = (SELECT TOP 1 CO_RECIBO FROM RECIBOS WHERE PENDIENTE = 'S') UPDATE RECIBOS SET PENDIENTE = 'N' WHERE CO_RECIBO = @coRecibo END
|
Estructura GOTO
La sentencia goto nos permite desviar el flujo de ejecución hacia una etiqueta. Fué muy utilizada en versiones anteriores de SQL Server conjuntamente con la variable de sistema @@ERROR para el control de errores.
Actualmente, se desaconseja el uso GOTO, recomendandose el uso de TRY - CATCH para la gestion de errores.
DECLARE @divisor int, @dividendo int, @resultado int
SET @dividendo = 100 SET @divisor = 0 SET @resultado = @dividendo/@divisor IF @@ERROR > 0 GOTO error PRINT 'No hay error' RETURN error: PRINT 'Se ha producido una division por cero' |