SQL Server Programacion Avanzada
SQL Server Programacion Avanzada
SQL Server Programacion Avanzada
UNIDAD DE
APRENDIZAJE
TEMARIO
ACTIVIDADES PROPUESTAS
Las funciones son rutinas que permiten encapsular sentencias TRANSACT-SQL que
se ejecutan frecuentemente.
Las funciones de usuario son definidas para crear una rutina reutilizables que se
pueden utilizar en las siguientes maneras:
• En TRANSACT-SQL como SELECT
• En las aplicaciones de llamar a la función
• En la definición de otra función definida por el usuario
• Para parametrizar una vista o mejorar la funcionalidad de una vista indizada
• Para definir una columna en una tabla
• Para definir una restricción CHECK en una columna
• Para reemplazar a un procedimiento almacenado
Son aquellas funciones donde retornan un valor único: tipo de datos como int, Money,
varchar, real, etc. Pueden ser utilizadas en cualquier lugar, incluso, incorporada dentro
de las sentencias SQL.
Ejemplo: Crear una función que retorne el precio promedio de todos los productos
-- MOSTRAR EL RESULTADO
PRINT DBO.PRECIOPROMEDIO()
Ejemplo: Defina una función donde ingrese el id del empleado y retorne la cantidad de
pedidos registrados en el presente año
Las funciones de tabla en línea son las funciones que devuelven la salida de una
simple declaración SELECT. La salida se puede utilizar adentro de JOINS o querys
como si fuera una tabla de estándar.
Ejemplo: Defina una función que liste los registros de los clientes, e incluya el nombre
del Pais.
-- EJECUTANDO LA FUNCION
SELECT * FROM DBO.CLIENTES() WHERE PAIS='CHILE'
GO
Ejemplo: Defina una función que liste los registros de los pedidos por un determinado
año, incluya el nombre del producto, el precio que fue vendido y la cantidad vendida
-- EJECUTANDO LA FUNCION
SELECT * FROM DBO.PEDIDOSAÑO(2010)
GO
Son similares a los procedimientos almacenados excepto que vuelven una tabla. Este
tipo de función se usa en situaciones donde se requiere más lógica y proceso. Lo que
sigue es la sintaxis para unas funciones de tabla de multisentencias:
Ejemplo: Defina una función que retorne el inventario de los productos registrados en
la base de datos.
-- EJECUTANDO LA FUNCION
SELECT * FROM DBO.INVENTARIO()
GO
Ejemplo: Defina una función que permita generar un reporte de ventas por empleado,
en un determinado año. En este proceso, la función debe retornar: los datos del
empleado, la cantidad de pedidos registrados y el monto total por empleado
SUM(PRECIOUNIDAD*CANTIDAD)
FROM VENTAS.PEDIDOSCABE PC JOIN VENTAS.PEDIDOSDETA PD
ON PC.IDPEDIDO = PD.IDPEDIDO JOIN VENTAS.EMPLEADOS E
ON E.IDEMPLEADO = PC.IDEMPLEADO
WHERE YEAR(FECHAPEDIDO) = @Y
GROUP BY E.IDEMPLEADO, APELLIDOS
RETURN
END
GO
3.1.1.4 Limitaciones
Las funciones definidas por el usuario tienen algunas restricciones. No todas las
sentencias SQL son válidas dentro de una función. Las listas siguientes enumeran las
operaciones válidas e inválidas de las funciones:
Válido:
• Las sentencias de asignación
• Las sentencias de Control de Flujo
• Sentencias SELECT y modificación de variables locales
• Operaciones de cursores sobre variables locales Sentencias INSERT,
UPDATE, DELETE con variables locales
Inválidas:
• Armar funciones no determinadas como GetDate()
• Sentencias de modificación o actualización de tablas o vistas
• Operaciones CURSOR FETCH que devuelven datos del cliente
• Incluir parámetros
• Llamar a otros procedimientos
• Devolver un valor de estado a un procedimiento de llamada o lote para indicar el
éxito o el fracaso del mismo y la razón de dicho fallo.
• Devolver valores de parámetros a un procedimiento de llamada o lote
• Ejecutarse en SQL Server remotos
Por ejemplo: Defina un procedimiento almacenado que liste todos los clientes
-- PROCEDIMIENTO ALMACENADO
CREATE PROCEDURE USP_CLIENTES
AS
SELECT IDCLIENTE AS CODIGO,
NOMBRECIA AS CLIENTE,
DIRECCION,
TELEFONO
FROM VENTAS.CLIENTES
GO
O simplemente
Por ejemplo: Cree un procedimiento almacenado que permita buscar los datos de los
pedidos registrados en una determinada fecha. El procedimiento deberá definir un
parámetro de entrada de tipo DateTime
O simplemente, colocar la lista de los valores el cual será asignada a cada parámetro,
donde el primer valor le corresponde a @f1
La dirección de un parámetro puede ser de entrada, que indica que un valor se pasa al
parámetro de entrada de un procedimiento almacenado o de salida, que indica que el
procedimiento almacenado devuelve un valor al programa que lo llama mediante un
parámetro de salida. El valor predeterminado es un parámetro de entrada.
Para especificar un parámetro de salida, debe indicar la palabra clave OUTPUT en la
definición del parámetro del procedimiento almacenado. El programa que realiza la
llamada también debe utilizar la palabra clave OUTPUT al ejecutar el procedimiento
almacenado, a fin de guardar el valor del parámetro en una variable que se pueda
utilizar en el programa que llama.
Por ejemplo: Cree un procedimiento almacenado que muestre los datos de los
pedidos, los productos que fueron registrados por cada pedido, el precio del producto y
la cantidad registrada por un determinado cliente y año. El procedimiento recibirá
como parámetro de entrada el código del cliente y el año. Considere que el parámetro
año tendrá un valor por defecto: el año del sistema.
Por ejemplo: Implemente un procedimiento almacenado que imprimir cada uno de los
registros de los productos, donde al finalizar, visualice el total del inventario (Suma de
cantidad de productos)
-- CERRAR EL CURSOR
CLOSE MI_CURSOR
-- LIBERAR EL RECURSO
DEALLOCATE MI_CURSOR;
USP_REPORTEPEDIDOSXAÑOXEMPLEADO 2
GO
Para este caso, hemos utilizado la instrucción MERGE que evalúa la existencia de un
registro. Si existe, actualizará los datos, sino agrega el registro.
-- PARÁMETROS DE PEDIDOSDETA
@IDPROD INT,
@PRE DECIMAL,
@CANT INT
AS
Esta forma de procesar las operaciones de pedidos sería errónea, ya que cada
instrucción se ejecutaría y confirmaría de forma independiente, por lo que un error en
alguna de las operaciones dejaría los datos erróneos en la base de datos.
BEGIN TRY
/*Bloque de instrucciones a validar*/
END TRY
BEGIN CATCH
/*Bloque de instrucciones que se ejecutan si ocurre un ERROR*/
END CATCH
-- CONTROLAR EL PROCESO
IF @@ERROR = 0
BEGIN
-- CONFIRMACIÓN DE LA INSERCIÓN
COMMIT TRAN TCLIENTE
PRINT 'CLIENTE REGISTRADO'
END
ELSE
BEGIN
PRINT @@ERROR
-- DESHACER LA INSERCIÓN
ROLLBACK TRAN TCLIENTE
END
GO
Para un mejor control de los errores, ejecutamos los procesos dentro del bloque TRY
CATCH, donde en caso que las operaciones hayan tenido éxito, ejecutará COMMIT
TRAN, pero en caso de error CATCH, ejecutará ROLLBACK TRAN, tal como se
muestra en el siguiente ejercicio.
-- CONFIRMANDO LA ACTUALIZACION
COMMIT TRAN TPEDIDO
PRINT 'PEDIDO REGISTRADO'
END TRY
BEGIN CATCH
PRINT @@ERROR
ROLLBACK TRAN TPEDIDO
END CATCH
GO
SOURCE.IDPAIS, TARGET.TELEFONO=SOURCE.FONOCLIENTE
WHEN NOT MATCHED THEN
INSERT VALUES(SOURCE.IDCLIENTE,SOURCE.NOMCLIENTE,
SOURCE.DIRCLIENTE, SOURCE.IDPAIS, SOURCE.FONOCLIENTE)
WHEN NOT MATCHED BY SOURCE THEN
DELETE ;
PRINT 'TRANSACCION COMPLETADA'
COMMIT TRAN BK
END TRY
BEGIN CATCH
PRINT @@ERROR
ROLLBACK TRAN
END CATCH
GO
Los disparadores pueden usarse para imponer la integridad de referencia de los datos
en toda la base de datos. Los disparadores también permiten realizar cambios “en
cascada” en tablas relacionadas, imponer restricciones de columna más complejas
que las permitidas por las reglas, compara los resultados de las modificaciones de
datos y llevar a cabo una acción resultante.
A. Disparador de Inserción
Cuando se inserta una nueva fila en una tabla, SQL Server inserta los nuevos valores
en la tabla INSERTED el cual es una tabla del sistema. Está tabla toma la misma
estructura del cual se originó el TRIGGER, de tal manera que se pueda verificar los
datos y ante un error podría revertirse los cambios.
Cree un TRIGGER que permita insertar los datos de un Producto siempre y cuando la
descripción o nombre del producto sea único.
B. Disparador de Eliminación
Cuando se elimina una fila de una tabla, SQL Server inserta los valores que fueron
eliminados en la tabla DELETED el cual es una tabla del sistema. Está tabla toma la
misma estructura del cual se origino el TRIGGER, de tal manera que se pueda
verificar los datos y ante un error podría revertirse los cambios. En este caso, la
reversión de los cambios significará restaurar los datos eliminados.
Cree un TRIGGER el cual permita eliminar Clientes los cuales no han registrado algún
pedido. De eliminarse algún Cliente que no cumpla con dicha condición la operación
no deberá ejecutarse.
C. Disparador de Actualización
Cuando se actualiza una fila de una tabla, SQL Server inserta los valores que antiguos
en la tabla DELETED y los nuevos valores los inserta en la tabla INSERTED. Usando
estas dos tablas se podrá verificar los datos y ante un error podrían revertirse los
cambios.
Por ejemplo, cuando el valor que se actualiza en un campo de tarifa de una hora de
trabajo de una tabla de planilla excede un valor específico, se puede definir un
desencadenador para producir un error y revertir la transacción o insertar un nuevo
registro en un registro de auditoría antes de insertar el registro en la tabla de planilla.
A. INSTEAD OF INSERT
Se pueden definir desencadenadores INSTEAD OF INSERT en una vista o tabla para
reemplazar la acción estándar de la instrucción INSERT. Normalmente, el
desencadenador INSTEAD OF INSERT se define en una vista para insertar datos en
una o más tablas base.
B. INSTEAD OF UPDATE
Se pueden definir desencadenadores INSTEAD OF UPDATE en una vista o tabla para
reemplazar la acción estándar de la instrucción UPDATE. Normalmente, el
desencadenador INSTEAD OF UPDATE se define en una vista para modificar datos
en una o más tablas. Las instrucciones UPDATE que hacen referencia a vistas que
contienen desencadenadores INSTEAD OF UPDATE deben suministrar valores para
todas las columnas que no admiten valores NULL a las que hace referencia la cláusula
SET
C. INSTEAD OF DELETE
Se pueden definir desencadenadores INSTEAD OF DELETE en una vista o una tabla
para reemplazar la acción estándar de la instrucción DELETE. Normalmente, el
desencadenador INSTEAD OF DELETE se define en una vista para modificar datos en
una o más tablas. Las instrucciones DELETE no especifican modificaciones de los
valores de datos existentes. Las instrucciones DELETE sólo especifican las filas que
se van a eliminar. La tabla inserted pasada a un desencadenador DELETE siempre
está vacía. La tabla deleted enviada a un desencadenador DELETE contiene una
imagen de las filas en el estado que tenían antes de emitir la instrucción DELETE
• Cada disparador puede aplicarse a una sola tabla. Sin embargo, un mismo disparador
se puede aplicar a las tres acciones del usuario: UPDATE, INSERT y DELETE.
• No se puede crear un disparador en una vista ni en una tabla temporal, aunque los
disparadores pueden hacer referencia a las vistas o tablas temporales.
• Los disparadores no se permiten en las tablas del sistema. Aunque no aparece ningún
mensaje de error su crea un disparador en una tabla del sistema, el disparador no se
utilizará.
Resumen
Las funciones definidas por el usuario, en tiempo de ejecución de lenguaje
TRANSACT-SQL o común (CLR), acepta parámetros, realiza una acción, como un
cálculo complejo, y devuelve el resultado de esa acción como un valor. El valor de
retorno puede ser un escalar (único) valor o una tabla.
Las funciones escalares son aquellas funciones donde retornan un valor único: tipo
de datos como int, Money, varchar, real, etc. Pueden ser utilizadas en cualquier
lugar, incluso, incorporada dentro de las sentencias SQL. Las funciones de tabla en
línea son las funciones que devuelven la salida de una simple declaración
SELECT. La salida se puede utilizar adentro de JOINS o querys como si fuera una
tabla de estándar. Las funciones de tabla multisentencias son similares a los
procedimientos almacenados excepto que vuelven una tabla
Los procedimientos almacenados son grupos formados por instrucciones SQL y el
lenguaje de control de flujo. Cuando se ejecuta un procedimiento, se prepara un
plan de ejecución para que la subsiguiente ejecución sea muy rápida. Los
procedimientos almacenados pueden:
1. Incluir parámetros
2. Llamar a otros procedimientos
3. Devolver un valor de estado a un procedimiento de llamada o lote para
indicar el éxito o el fracaso del mismo y la razón de dicho fallo.
4. Devolver valores de parámetros a un procedimiento de llamada o lote
5. Ejecutarse en SQL Server remotos
Un procedimiento almacenado se comunica con el programa que lo llama
mediante sus parámetros. Cuando un programa ejecuta un procedimiento
almacenado, es posible pasarle valores mediante los parámetros del
procedimiento. Estos valores se pueden utilizar como variables estándar en el
lenguaje de programación TRANSACT-SQL. El procedimiento almacenado
también puede devolver valores al programa que lo llama mediante parámetros
OUTPUT. Un procedimiento almacenado puede tener hasta 2.100 parámetros,
cada uno de ellos con un nombre, un tipo de datos, una dirección y un valor
predeterminado
Si desea saber más acerca de estos temas, puede consultar las siguientes
páginas:
http://www.devjoker.com/contenidos/catss/292/Transacciones-en-Transact-SQL.aspx
Aquí hallará los conceptos de Transacciones en TRANSACT SQL.
http://www.sqlmax.com/func2.asp
http://msdn.microsoft.com/es-es/library/ms189260.aspx