Beruflich Dokumente
Kultur Dokumente
Importante
Es recomendable crear índices para optimizar las consultas.
Se pueden crear un índice agrupado, que se crea de manera automática en la
tabla con clave primaria (primary key) y 999 índices no agrupados en la misma
tabla o vista.
En la lista de campos por el cual va a ordenar los registros de la tabla o vista
pueden haber hasta 32 campos.
El orden puede ser ascendente (Asc) o descendente (Desc). El valor por defecto
es Asc.
Las columnas con tipos de datos ntext,text, varchar
(max), nvarchar(max), varbinary (max), xml, o imagen no se pueden crear
índices.
Se puede crear índices para las tablas particionadas, estos índices se les llama
índices particionados. (Ver índices particionados)
Sintaxis
Para la creación de índices vamos a dividir la sintaxis de acuerdo al tipo de índice.
Crear un índice no agrupado
Ejercicios
Usando la base de datos Norwhwind
use northwind
go
sp_help Categories
go
Modificar un índice
Reindexar o reconstruir un índice es una operación que se sugiere para planes de
mantenimiento, esto reordena los registros y puede optimizar las consultas.
Modificación de Índices
Instrucción Alter Index
Modifica un índice en una tabla o vista. Al modificar se puede deshabilitar,
reorganizar (reconstruir) o cambiar sus opciones.
Reconstruir un índice
Alter index NombreIndice on Tabla/Vista Rebuild
Ejercicios
Usando Northwind
use Northwind
go
Eliminando un índice
La instrucción Drop Index permite eliminar los índices de una tabla o vista. La
eliminación de un índice tiene que ser decidida con cuidado, si el índice permitía
que alguna consulta sea más óptima, eliminarlo podría causar que las consultas y
reportes en los sistemas sean más lentos.
Sintaxis
Drop index NombreIndice on Tabla/Vista
Indices – ejercicios
By Trainer SQL in Índices
Indices
Los índices permiten ordenar los registros de una tabla o vista de acuerdo a uno a
mas campos en orden ascendente o descendente. (Ver índices)
Ejercicios
Usando la base de datos Northwind
use Northwind
go
Crear INDICES
Eliminar un índice:
Índices particionados
By Trainer SQL in Bases de Datos, Índices
Índices particionados
Los índices particionados son tipos de índices usados en tablas particionadas.
(Ver Tablas particionadas).
Conceptos previos
La partición facilita el uso de tablas e índices grandes, ya que permite administrar y tener
acceso a subconjuntos de datos de forma rápida y eficaz, a la vez que mantiene la
integridad de la recopilación de datos.
Si se utilizan las particiones, una operación como la carga de datos desde un sistema
OLTP a un sistema OLAP tarda solo unos segundos, en lugar de los minutos y las horas
que tardaba en versiones anteriores
de SQL Server.
Las operaciones de mantenimiento que se realizan en los subconjuntos de
datos también se realizan de forma más eficaz porque estas operaciones solo afectan a
los datos necesarios, en lugar de a toda la tabla.
Las tablas e índices con particiones únicamente están disponibles en las ediciones
Enterprise, Developer y Evaluation de SQL Server.
Los datos de tablas e índices con particiones se dividen en unidades que pueden
propagarse por más de un grupo de archivos de la base de datos.
Los datos se dividen en sentido horizontal, de forma que los grupos de filas se asignan a
particiones individuales.
La tabla o el índice se tratarán como una sola entidad lógica cuando se realicen consultas
o actualizaciones en los datos. Las particiones de un índice o una tabla deben
encontrarse en la misma base de datos.
Las tablas y los índices con particiones admiten todas las propiedades y características
asociadas con el diseño y la consulta de tablas e índices estándar, incluidas las
restricciones, los valores predeterminados, los valores de identidad y marca de tiempo,
así como los desencadenadores. Por tanto, si desea implementar una vista con
particiones local en un servidor, puede interesarle implementar en su lugar una tabla con
particiones.
La decisión acerca del uso de las particiones depende básicamente del tamaño actual o
futuro de la tabla, la forma en que se utiliza y el rendimiento que presenta en las
consultas de usuario y las operaciones de mantenimiento.
Ejemplo
Para crear índices particionados vamos a crear primero una tabla
particionada.
Este ejercicio muestra una tabla con 5 particiones en tres grupos de
archivos,
la base de datos está creada en las unidades C: y D:
xp_create_subdir ‘C:\Parte’
go
xp_create_subdir ‘D:\Logica’
go
Create database Sistemas
on Primary (name= ‘Sistemas01’, Filename = ‘C:\Parte\Sistemas01.mdf’),
Filegroup VENTAS (name= ‘Sistemas02’, Filename = ‘C:\Parte\Sistemas02.ndf’),
Filegroup RECURSOS (name= ‘Sistemas03’, Filename =
‘C:\Parte\Sistemas03.ndf’)
log on
(name= ‘Tran01’, Filename = ‘C:\Parte\Tran01.ldf’)
go
use Sistemas
go
select ProductosCodigo,
UPPER(left(ProductosDescripcion,4)+
Rtrim(Ltrim(iif(len(ProductosCodigo)=1,’000’+Ltrim(ProductosCodigo),
’00’+Ltrim(ProductosCodigo))))) + Rtrim(LTrim(‘PR’))
As ‘Nuevo Código’
from Productos
go
Note que para hacer mas eficiente el índice se puede incluir (usando
include) el campo Descripción. (Ver Include en Índices)
Uso de Include en Índices
By Trainer SQL in Índices
Limitaciones
Se usan en sólo índices no agrupados
Se pueden usar todos los tipos de datos excepto text, ntext, and image
No se pueden eliminar las columnas incluidas con Include salvo que se elimine primero el
índice.
Ejercicios
Usando la base de datos Northwind
use Northwind
go
1. Crear un índice para la tabla productos por la descripción, incluir los
campos Unidad y Precio
Las imágenes siguientes muestran las propiedades del índice, para ver estas
propiedades despliegue el nodo índices en la tabla Employees, luego puede
pulsar doble click en el índice que desea ver sus propiedades.
Ver los índices creados
Para visualizar los índices creados se puede filtrar de acuerdo al nombre.
if not exists
(select * from sys.indexes where name = ‘ClientesContactoIDX’)
Begin
Create index ClientesContactoIDX
on Customers([ContactName])
include (Country, Region , City)
with fillfactor = 70
End
Else
Begin
Create index ClientesContactoIDX
on Customers([ContactName])
include (Country, Region , City)
with (fillfactor = 70, drop_existing = on)
End
go
Ejercicios
Como crear vistas indizadas en SQL Server
By Trainer SQL in Índices
Ejercicios
1. Crear una vista para los productos
Note que se ha incluído los campos Precio y Stock. Ver Include en Índices
Procedimientos Almacenados
By Trainer SQL in Programación
Procedimientos Almacenados
Un procedimiento almacenado son instrucciones T-SQL almacenadas con un
nombre en la base de datos.
Rendimiento mejorado
Los procedimientos almacenados se compila la primera vez que se ejecutan y
crean un plan de ejecución que vuelve a usarse en posteriores ejecuciones.
Tipos de procedimientos
Definidos por el usuario
Se crea por el usuario en las bases de datos definidas por el usuario o en las de
sistema (Master, Tempdb, Model y MSDB)
Sintaxis
Para crear un procedimiento almacenado se utiliza
Create procedure NombreProcedimiento
(
@PrimerParametro TipoDato,
@SegundoParametro TipoDato,…
)
As
Instrucciones del SP
go
Para modificar un SP
Alter procedure NombreProcedimiento
(
@PrimerParametro TipoDato,
@SegundoParametro TipoDato,… cambios
)
As
Instrucciones del SP con cambios
go
Eliminar un SP
Drop procedure NombreProcedimiento
go
Ejercicios
Use Northwind
go
Procedimientos Almacenados
Ejercicio para el uso de los procedimientos almacenados con los datos de una
tabla.
En este ejercicio se crea una tabla para carreras en la Universidad SQL, se crean
los procedimientos almacenados para insertar un registro, modificar los datos del
registro, listar los registros ordenados por descripción y borrar un registro.
Exec spCarrerasInsertarNuevo
@CarrerasVacantes =80 ,@CarrerasEstado =’A’,@CarrerasCodigo =’96325′,
@CarrerasDescripcion=’CONTABILIDAD’,@CarrerasAcreditada=’S’
go
Listado de Carreras
SELECT * FROM Carreras
go
Crear un Índice por Descripción de la carrera (Ver Índices)
create index CarrerasDescripcionIDXa on Carreras(CarrerasDescripcion)
with (fillfactor = 80)
go
Procedimientos para Listado, note que no aparecen los
que tienen en el estado la letra E que indica que han sido
eliminadas.
Create procedure spCarrerasListado
As
select CarrerasCodigo, CarrerasDescripcion, CarrerasAcreditada,
CarrerasVacantes, CarrerasEstado from Carreras
where CarrerasEstado <> ‘E’
order by CarrerasDescripcion
go
go
Parámetros
Los parámetros se usan para intercambiar datos entre las aplicaciones y los
procedimientos almacenados o la herramienta que ejecutó el procedimiento
almacenado.
Los parámetros de entrada permiten pasar un valor de datos al procedimiento
almacenado.
Los parámetros de salida permiten al procedimiento almacenado devolver un
valor
Los procedimientos almacenados devuelven un código de retorno de tipo entero.
El valor de retorno por defecto es CERO si no se establece explícitamente un
valor diferente
Ejemplos
Los siguientes ejemplos muestran como usar los parámetros de salida en
procedimientos almacenados.
Usando Northwind
use Northwind
go
Ejercicio 1
Procedimiento almacenado que reporta el número de productos de una
determinada categoría
Para ejecutar el procedimiento debemos crear antes una variable que permita
capturar el valor devuelto por el parámetro de salida del procedimiento.
Tomaremos como ejemplo la categoría 3.
Ejercicio 2
Procedimiento almacenado que reporta la cantidad de productos que es
necesario comprar con urgencia. (Productos cuyas Unidades en Stock es
menor a las unidades en Orden)
Para ejecutar el procedimiento debemos crear antes una variable que permita
capturar el
valor devuelto por el parámetro de salida del procedimiento.
Función Descripción
Ejemplo
El siguiente ejemplo muestra una división entre CERO, lo que arroja error,
luego se muestran los valores de cada función. Se utiliza la estructura Try
Catch cuya explicación está al final de este artículo.
BEGIN TRY
DECLARE @Valor1 Numeric(9,2),@Valor2 Numeric(9,2), @Division Numeric(9,2)
SET @Valor1 = 100
SET @Valor2 = 0
SET @Division = @Valor1/@Valor2
PRINT ‘La división no reporta error’
END TRY
BEGIN CATCH
select ERROR_NUMBER() As ‘Nº de Error’, ERROR_SEVERITY() As ‘Severidad’,
ERROR_STATE() As ‘Estado’, ERROR_PROCEDURE() As ‘Procedimiento’,
ERROR_LINE() As ‘Nº línea’,
ERROR_MESSAGE() As ‘Mensaje’
END CATCH
La Función @@ERROR
La función @@ERROR almacena el número de error producido por la última
sentencia Transact SQL ejecutada, si no se ha producido ningún error el valor de
la función es CERO.
Se puede usar esta función para controlar los errores usando una estructura If
Ejemplo:
El siguiente ejemplo muestra una división entre CERO, lo que arroja error,
luego se da consistencia al error con una estructura If
Nivel de Descripción
gravedad
0-9 Mensajes informativos que devuelven información de estado o informan sobre errores q
de 0 a 9.
Nivel de Descripción
gravedad
12 Una gravedad especial para consultas que no utilizan bloqueo debido a sugerencias de c
instrucciones podrían producir datos incoherentes, ya que no se adoptan bloqueos para g
17-19 Indica errores de software que no pueden ser corregidos por el usuario. Informe al admi
17 Indica que la instrucción ha hecho que SQL Server se quede sin recursos (como, por eje
los límites establecidos por el administrador del sistema.
20-24 Indica problemas del sistema y son errores irrecuperables, lo que significa que ya no est
lote. La tarea registra información sobre lo acontecido y, a continuación, finaliza. En la
delMotor de base de datos . Si esto ocurre, dependiendo del problema, la aplicación pod
Los mensajes de error incluidos en este intervalo pueden afectar a todos los procesos qu
u objeto está dañado. Los mensajes de error con nivel de gravedad entre 19 y 24 se escri
20 Indica que una instrucción ha encontrado un problema. Puesto que el problema ha afecta
21 Indica que se ha encontrado un problema que afecta a todas las tareas de la base de dato
22 Indica que la tabla o índice especificado en el mensaje ha sido dañado por un problema
23 Indica que se sospecha de la integridad de toda la base de datos debido al daño causado
24 Indica un error en los medios. Puede que el administrador del sistema tenga que restaura
Mensajes de error
SQL Server tienen una vista de catálogo con los mensajes definidos por defecto,
la vista es sys.messages, a la cual se le pueden añadir mensajes de error con
sus parámetros respectivos usando el procedimiento
almacenado sp_addmessage.
El procedimiento sp_addmessage
Permite agregar un mensaje de error definido por el usuario a la vista de catálogo
sys.messages
Sintaxis:
Donde:
[ @msgnum= ] msg_id Especifica el Id del mensaje, se pueden iniciar en 50001,
el valor máximo es 2,147,483,647.
[ @severity= ] severidad Indica el nivel de gravedad del error, puede ser un valor
entre 1 y 25.
[ @msgtext= ] ‘mensaje‘ Especifica el mensaje definido por el usuario.
[ @lang= ] ‘languaje’ Especifica el lenguaje.
Ejemplos:
Ejercicio 1
Agregar el mensaje para indicar que un porcentaje de descuento puede ser
entre 0 y 25%.
Note que es necesario insertar el mensaje para el idioma inglés y así poder
agregar el mensaje para español.
Use master
go
Execute sp_addmessage 50001, 16, ‘The discount percentage should be between
0 and 25%’, ‘us_english’ , false, replace
Execute sp_addmessage 50001, 16, ‘El porcentaje de descuento debe ser entre 0
y 25%’, ‘Spanish’ , false, replace
go
Ejercicio 2
Agregar el mensaje para indicar que un precio debe ser CERO o mayor.
Note que es necesario insertar el mensaje para el idioma inglés y así poder
agregar el mensaje para español.
Use master
go
Execute sp_addmessage 50002, 16,
‘The price should be 0 or greater’, ‘us_english’ , false, replace
Execute sp_addmessage 50002, 16,
‘El precio debe ser 0 o mayor’, ‘Spanish’ , false, replace
go
Donde:
[ @message_id = ] message_number Especifica el Id del mensaje
[ @parameter = ]’write_to_log‘ Especifica si se va a escribir en el log de
Windows
[ @parameter_value = ]’value’ Se utiliza con @parameter para indicar que el
error debe escribirse en el registro de aplicación de Microsoft Windows
Ejemplo
El siguiente ejemplo permite especificar que el mensaje de error creado se
escriba en el log de Windows.
Donde:
[ @msgnum = ] message_number Especifica el Id del mensaje
[ @lang = ] ‘language’ Especifica el lenguaje.
Ejemplo
El siguiente código elimina el mensaje creado con Id 50001
Sintaxis:
BEGIN TRY
Instrucciones Transact – SQL que pueden dar error
END TRY
BEGIN CATCH
Instrucciones Transact – SQL para manejar el error
END CATCH
Ejemplo:
Usando la base de datos Northwind, listar los registros de la tabla Ventas,
tenga en cuenta que la tabla no existe.
El select se incluirá en un procedimiento almacenado.
Use Northwind
go
El procedimiento almacenado
BEGIN TRY
Execute spListaVentas
END TRY
BEGIN CATCH
SELECT ERROR_NUMBER() AS ‘Nº Error’, ERROR_MESSAGE() AS ‘Mensaje’
END CATCH
Proceso para declarar, abrir, usar, cerrar y liberar los datos de un cursor
1. Declarar el cursor, utilizando DECLARE Cursor
2. Abrir el cursor, utilizando OPEN
3. Leer los datos del cursor, utilizando FETCH … INTO
4. Cerrar el cursor, utilizando CLOSE
5. Liberar el cursor, utilizando DEALLOCATE
2. Abrir el cursor
OPEN NombreDelCursor
3. Lectura de los datos del cursor, va a depender del tipo de cursor. Hay de
avance hacia adelante solamente y Scroll.
FETCH NombreDelCursor
BEGIN
4. Cerrar el cursor
CLOSE NombreDelCursor
DEALLOCATE NombreDelCursor
Ejercicios
1. Cursor que reporta los Empleados
select @@FETCH_STATUS
go
— Cerrar el cursor, liberar de memoria
close cursorEmpleados
Deallocate cursorEmpleados
go
Open cursorCategorias
go
Open cursorCategoriasListadoProductos
Declare @CodigoCategoria int, @NombreCategoria nvarchar(15)
Fetch cursorCategoriasListadoProductos into @CodigoCategoria,
@NombreCategoria
Print
‘============================================================’
Print ‘============ Listado de Productos por categoria ==========’
Print
‘============================================================’
Print ”
Begin
Begin
Print ”
Close cursorProductosCategoria
Deallocate cursorProductosCategoria
Close cursorCategoriasListadoProductos
Deallocate cursorCategoriasListadoProductos
go
Print ‘=====================================’
Print ‘=====PRODUCTOS POR CATEGORIA=========’
Print ‘=====================================’
While (@@FETCH_STATUS = 0)
Begin
Print ‘Código Categoria: ‘ + Ltrim(Str(@CodigoCategoria))
Print ‘Nombre Categoria: ‘ + Ltrim(@NombreCategoria)
Print ‘===================================================’
— Definir el cursor para los productos de la categoria actual
Declare cursorProductoPorCategoria cursor for
select ProductID, ProductName, UnitPrice, UnitsInStock from Products
where CategoryID = @CodigoCategoria
Open cursorProductoPorCategoria
Declare @CodigoProducto Integer, @NombreProducto nvarchar(40), @Precio
Numeric(9,2), @Stock Numeric(9,2)
Fetch cursorProductoPorCategoria into @CodigoProducto, @NombreProducto,
@Precio, @Stock
Close cursorProductoPorCategoria
Deallocate cursorProductoPorCategoria
Print ”
— Acumulado Total
Set @CantidadTotaldeProductos = @CantidadTotaldeProductos +
@CantidadProductosPorCategoria
Set @ValorTotaldelStock = @ValorTotaldelStock + @ValorStockPorCategoria
Close cursorCategorias
Deallocate cursorCategorias
go
Cursores
Elemento que almacena en memoria el resultado de un Select. Para mayor
información ver Cursores en SQL Server
Pasos:
1. Declarar el cursor, utilizando DECLARE
2. Abrir el cursor, utilizando OPEN
3. Leer los datos del cursor, utilizando FETCH … INTO
4. Cerrar el cursor, utilizando CLOSE
5. Liberar el cursor, utilizando DEALLOCATE
OPEN <NOMBRE_CURSOR>
WHILE (@@FETCH_STATUS = 0)
BEGIN
FETCH <NOMBRE_CURSOR> INTO <LISTA_VARIABLES>
…
END — FIN DEL BUCLE WHILE
CLOSE <NOMBRE_CURSOR>
DEALLOCATE <NOMBRE_CURSOR>
Ejercicios
Cursor que liste las categorias, el resultado se muestra como sigue:
1 Beverages
2 Condiments
3 Confections
4 Dairy Products
5 Grains/Cereals
6 Meat/Poultry
7 Produce
8 Seafood */
CURSORES ANIDADOS
Cursor que muestre las categorías y de cada categoría los productos
Cursor Scroll:
Para leer los datos del cursor definido como Scroll, en la instrucción Fetch se
puede usar las siguientes palabras para desplazarse.
— Último
Fetch Last from cursorScrollCategorias
go
— Retroceder 3
Fetch Relative -3 from cursorScrollCategorias
go
— Al número 6
Fetch Absolute 6 from cursorScrollCategorias
go
— Siguiente
Fetch next from cursorScrollCategorias
go
— Anterior
Fetch prior from cursorScrollCategorias
go
— Cerrar y liberar
Close cursorScrollCategorias
Deallocate cursorScrollCategorias
go
Funciones definidas por el usuario FDU
By Trainer SQL in Programación
Ejercicios
Usando Northwind
use Northwind
go
FDU que retorne los productos con tengan mas Unidades en Orden que
Stock actual
Create function fduProductoCompraUrgente () returns Table
As
Return (select * from Products where UnitsOnOrder > UnitsInStock)
go
Para usar la función creada
select * from fduProductoCompraUrgente()
go
Para las Órdenes del Cliente se puede usar una sub consulta. (Ver Sub consultas)
SELECT * FROM Orders where CustomerID = (select CustomerID from
Customers
where CompanyName = ‘Antonio Moreno Taquería’)
go
En una FDU
Create function fduOrdenesPorCliente(@Cliente nvarchar(40)) Returns Table
As
Return (SELECT * FROM Orders
where CustomerID = (select CustomerID from Customers
where CompanyName =@Cliente ))
go
AS
BEGIN
Cuerpo
RETURN Expresión
END
RETURN InstruccionSelect
— Usando Northwind
use Northwind
go
— Crear una función para retornar el total de Categorías
As
Begin
Return @CantidadCategorias
End
go
— Prueba:
go
go
go
— Crear una función que reporte el total de artículos en Stock de– cualquier
categoría
As
Begin
Return @TotalStock
End
go
— Categoria 1
go
— Categoria 5
go
go
As
Begin
End
Else
Begin
End
go
— Pruebas
Exec spCantidadxClientesxPais ‘France’
go
FDU – Cantidad de vocales y
consonantes en un texto
By Trainer SQL in Programación
use Northwind
go
Funciones definidas por el usuario con
valores de tabla
By Trainer SQL in Consultas, Funciones en SQL Server, Programación, Registros - Vistas
Ejemplos
Usando la base de datos Northwind
use Northwind
go
Ejercicio 1
Crear una función definida por el usuario con valores de tabla que
muestre los proveedores de un determinado país. Para visualizar el
resultado se incluirá el nombre del país
— Creamos la función
Sinónimos
Se lo puede definir como un identificador de un objeto en la BD. El objeto del que
se crea el sinónimo no es necesario que exista al momento de crear el sinónimo,
SQL Server comprueba la existencia del objeto en tiempo de ejecución.
Los sinónimos pueden reducir los errores al hacer referencia a los objetos en
instrucciones Transact SQL. Los sinónimos se crean en la base de datos abierta.
Ejercicios
Usando la base de datos Northwind
use Northwind
go
En un post anterior se explica la creación de tablas con campos XML (Ver Datos
XML), ahora se va a crear
una base de datos para una clínica veterinaria y una tabla de Propietarios con
sus mascotas en un campo XML. (Ver Campos XML)
use ClinicaVet
go
Para insertar registros que contienen campos de tipo XML se puede proceder de
la forma como se presenta líneas arriba, pero lo recomendable es guardar los
datos en una variable de tipo XML y luego usar esa variable en la instrucción
Insert.
Para leer los datos de una variable de tipo XML en SQL Server se utiliza el
método Query para la variable de tipo XML
Triggers
Trainer SQLProgramación
Triggers
Un desencadenador o Trigger es una clase de procedimiento almacenado que se
ejecuta automáticamente cuando se realiza una transacción en las bases de datos.
Tipos de Triggers
Existen los siguientes tipos de Triggers
1. Los Triggers DML se ejecutan cuando se realizan operaciones de manipulación de
datos (DML). Los eventos DML son instrucciones INSERT, UPDATE o DELETE
realizados en una tabla o vista.
2. Los Triggers DDL se ejecutan al realizar eventos de lenguaje de definición de datos
(DDL). Estos eventos corresponden a instrucciones CREATE, ALTER y DROP.
3. Los Triggers Logon, que se disparan al ejecutarse un inicio de sesión en SQL
Server.
Consideraciones
Una tabla puede tener un máximo de tres triggers: uno de actualización, uno de
inserción y uno de eliminación.
Cada trigger puede aplicarse a una sola tabla o vista. Por otro lado, un mismo trigger
se puede aplicar a las tres acciones: UPDATE, INSERT y DELETE.
No se puede crear un trigger en una vista ni en una tabla temporal, pero el trigger
puede hacer referencia a estos objetos.
Los trigger no se permiten en las tablas del sistema.
Las tablas Inserted y Deleted
Son tablas especiales que tienen la misma estructura de las tablas que han
desencadenado la ejecución del trigger.
La tabla Inserted está disponible en las operaciones INSERT y UPDATE.
La tabla Deleted está disponible en las operaciones UPDATE y DELETE.
Note que para una operación de actualización, las dos tablas pueden ser
utilizadas.
Ejercicios
Usando Northwind
use Northwind
go
Insertar Categorias
Trigger de Inserción
5. Crear un Trigger que permita comprobar que se inserta una categoría con
nombre diferente. La tabla Inserted será utilizada para comprobar si ya hay
una categoría con el mismo nombre que la insertada.
Trigger Instead Of
Realizar acciones después de las instrucciones de un procedimiento o las
escritas directamente por el usuario. (Ver Triggers Instead Of)
Notas importantes
1. Estos tipos de triggers cancelan la instrucción que hace que se dispare,
reemplazando
esta por las instrucciones del Trigger.
2. Generalmente se utilizan estos triggers en vistas
3. Las acciones que realice el trigger no deben cancelar la transacción que la
dispara sino ejecutar las instrucciones cambiadas que son el cuerpo del trigger.
Ejemplo
Usando la base de datos Northwind
use Northwind
go
Insertar un Cliente
Insertar un Proveedor
Note que al insertar registros en la vista debemos especificar todos los campos,
en el Trigger para los proveedores no se especifica el código porque es un campo
entero y es Identidad. (Ver Identity)
Triggers – Activar y Desactivar
By Trainer SQL in Programación
Desactivar el Trigger
Disable Trigger NombreTrigger on Tabla/Vista
Activar el Trigger
Enable Trigger NombreTrigger on Tabla/Vista
Ejercicio
Usando la base de datos Northwind
use Northwind
go
Actualizar Region
Eliminar varios registros, se requiere insertar varios. Por ejemplo una vez
insertados los registros con códigos 34, 87 y 25
Desactivar el Trigger
Disable Trigger NombreTrigger on Tabla/Vista
Activar el Trigger
Enable Trigger NombreTrigger on Tabla/Vista
Triggers Encriptados
Este artículo muestra como encriptar un trigger, es importante que en todo nivel
exista un cuidado con las instrucciones que realiza el trigger, la opción de
encriptación evita que de alguna forma se pueda visualizar las instrucciones del
Trigger usando el procedimiento almacenado (Ver Procedimientos Almacenados)
sp_helpText.
Los triggers DML son procedimientos que se disparan cuando en una tabla o vista
se realizan las instrucciones Insert, Update o Delete. Para mayor información Ver
Triggers.
Ejercicios
Usando la base de datos Northwind
use Northwind
go
Primero mostramos los registros para actualizar uno de ellos, el registro con
código 4 se cambiará la descripción por Sur.
Actualizar Region
Probando el Trigger
Ver las regiones
select * from Region
go
Activar el Trigger
Enable Trigger NombreTrigger on Tabla/Vista
Notas adicionales:
Se pueden encriptar también Procedimientos Almacenados, Funciones definidas
por el usuario y vistas, esto va a permitir un grado mayor de seguridad en los
objetos.
Para mayor información ver: Procedimientos almacenados, Funciones definidas
por el usuario y vistas.
Triggers Logon en SQL Server
By Trainer SQL in Programación
Triggers Logon
Como usar triggers logon en SQL Server
Puede utilizar los Triggers de inicio de sesión para auditar y controlar las sesiones
del servidor, como el seguimiento de la actividad de inicio de sesión, la restricción
de inicios de sesión en SQL Server o la limitación del número de sesiones para
un inicio de sesión específico.
<OpcionesTriggersLogon> ::=
[ ENCRYPTION ]
[ EXECUTE AS Clause ]
Procedimiento sp_settriggerorder
Define el primero y el último de los Triggers Logon
Ejemplo
USE Northwind
go
sp_settriggerorder @triggername= ‘dbo.trShippersInserta’, @order=’First’,
@stmttype = ‘INSERT’
GO
Ejercicio
Crear un Trigger Logon que deniegue intentos de inicio de sesión de SQL
Server iniciados por login TrainerSQL si ya hay tres sesiones de usuario
creadas por ese inicio de sesión.
USE master
go
CREATE LOGIN TrainerSQL WITH PASSWORD = ‘cl@v3F1n@1’
go
Para probar el Trigger, conectarse a la misma instancia más de tres veces con el
mismo inicio de sesión, en la figura se muestra la conexión
Consideraciones importantes
Cualquier modificación de datos realizada hasta el punto de ROLLBACK
TRANSACTION se revierte. Estas modificaciones incluyen las realizadas por el
desencadenador actual y las realizadas por desencadenantes anteriores que se
ejecutaron en el mismo evento.
Cualquier desencadenante restante para el evento específico no se ejecuta.
El Trigger actual continúa ejecutando las sentencias restantes que aparecen
después de la instrucción ROLLBACK.
Si alguna de estas declaraciones modifica los datos, las modificaciones no se
revierten.
Puede interesar
Triggers, definición y creación
Triggers DML encriptados
Triggers Logon
Triggers, activar y desactivar.
Ejemplos
Usando la base de datos Northwind
use Northwind
go
Para poder crear tablas, se debe eliminar el Trigger o solamente desactivar (Ver
Triggers Activar – Desactivar)
disable trigger trNoCrearModificarBorrarTablas on Database
go
2. Crear un Trigger que se dispare cuando se crea una vista y capture el evento
creado.
Para que el Trigger se dispare, crear un procedimiento almacenado para listar los
clientes
Borrar el SP
Drop procedure spClientesListado
go
Funciones de Cursor
Las funciones de cursor devuelven información de los cursores. (Ver cursores)
Función @Cursor_rows
Devuelve el número de filas del cursor abierto.
-1 El cursor es dinámico. Como los cursores dinámicos reflejan todos los cambio
cambia constantemente. Nunca se puede afirmar que se han recuperado todas l
0 No se han abierto cursores, no hay filas calificadas para el último cursor abiert
cancelado.
Ejemplo
— Crear un cursor para mostrar los Empleados
Declare cursorEmpleados Cursor for
select E.EmployeeID As ‘Código’, Empleado = E.LastName + Space(1)+
E.FirstName from Employees As E order by Empleado
Open cursorEmpleados
Fetch from cursorEmpleados
Print ‘========= EMPLEADOS ============= ‘
While @@FETCH_STATUS = 0
Begin
Fetch from cursorEmpleados
End
Close cursorEmpleados
Deallocate cursorEmpleados
go
Función Cursor_Status
Permite determinar si el resultado de un procedimiento almacenado ha devuelto
un cursor y un conjunto de resultados al recibir un parámetro.
Valor Descripción
Ejemplo
Crear un cursor con las categorías
Antes de Crear el cursor
select CURSOR_STATUS (‘global’,’cursorCategorias’) As ‘Antes de Crear’
go
Resultado: -3
Instrucción Merge
Realiza instrucciones de inserción de registros, actualización o eliminación de
registros en una tabla de destino en la misma base de datos o en otra base de
datos según los resultados de combinar los registros con una tabla de origen.
Sintaxis
La forma de usar Merge es la siguiente:
MERGE
[ TOP ( n ) [ PERCENT ] ]
[ INTO ] <Tabla_Destino> [ [ AS ] AliasTablaDestino ]
USING <Tabla_Origen> [ [ As ] AliasTablaOrigen]
ON <CondiciónMergeComparación>
[ WHEN MATCHED [ AND <Condición> ]
THEN <Isntrucción Si encuentra> ] [ …n ]
[ WHEN NOT MATCHED [ BY TARGET ] [ AND <Condición> ]
THEN <Instrucción Si NO Encuentra en Destino> ]
[ WHEN NOT MATCHED BY SOURCE [ AND <Condición> ]
THEN <Instrucción Si NO Encuentra en Origen> ] [ …n ]
Ejemplo
En este ejemplo, se tienen dos bases de datos cada una con una tabla de
Productos.
La base de datos Planes, con la tabla ProductosPlanes y la base de datos
Desarrollo con la tabla ProductosDesarrollo.
Haciendo el Merge
La tabla Origen es Productos de la base de datos Desarrollo y la tabla
Destino en Productos en la base de datos Planes
Insertar Registros
By Trainer SQL in Registros - Vistas
Insertar Registros
Para insertar registros en una tabla se utiliza la instrucción Insert.
Se pueden agregar registros también utilizando una consulta como origen de los
datos.
Insert permite agregar uno a o mas registros a la vez.
Sintaxis
Insert [into] NombreTabla [ ( Lista de columnas ) ]
VALUES ( DEFAULT | NULL | expression } [ ,…n] ) | Select….)
Donde
Into Palabra clave inicial para indicar a que tabla se insertarán los registros.
Values Palabra reservada para especificar los valores de cada campo en la lista de columnas.
Notas importantes:
La columna que tiene activada la propiedad Identity no se espacifica en la lista de
campos a insertar.
En lo posible se debe evitar los datos Null, los que ocurren cuando en una campo
no se escribe el dato a ingresar.
Si no se especifican los campos a insertar los datos, SQL Server supone que se
van a insertar todos los campos de la tabla.
Si la tabla tienen campos calculados, estos no se ingresan al usar Insert.
Es recomendable usar restricciones de tipo Default para evitar en las tablas los
valores Null.
Los campos que deben de ser obligatorios al insertar un registro se deben crear
usando la cláusula Not Null.
Para información de inserción de datos de tipo Image pulse aquí
Ejercicios
Usando Northwind
use Northwind
go
3. Insertar dos nuevas regiones, la tabla Region solamente tiene los campos
RegionID de tipo Int y RegionDescripcion de tipo nchar(50)
insert into Region values (6,’Antártida’),(7, ‘Bosques Albinos’)
go
4. Crear una tabla con los productos descontinuados y luego insertar los
registros.
— Creamos la tabla
5. Una tabla con campos calculados. Crearemos una tabla con campos
calculados, luego insertar registros.
— Insertar registros
insert into Promedios values (‘8588’,12,16,14)
go
Las imágenes pueden ocupar un poco mas de espacio en el disco que los datos
de tipo texto o los datos numéricos así como las fechas, si van a ser muchos
registros, es recomendable separar las imágenes en un grupo de archivos
diferente de donde están los datos del mismo registro usando la partición vertical
de la tabla. (Ver Partición Vertical)
Ejemplo
En este ejemplo se creará una base de datos y luego crear dos tablas, una con
empleados y otra con productos. Luego insertaremos los registros incluyendo las
fotos de los empleados y las imágenes de los productos. (Ver Insertar Registros)
Para que los ejercicios funcionen, antes de ejecutar los scripts, cree las carpetas
e inserte en ellas las imágenes a insertar.
Las fotos de los empleados se ubicarán en la carpeta D:\EmpleadosFotos y las
imágenes de los productos estarán en la carpeta D:\ProductosImagenes
La base de datos
Productos
Create table Productos
(
ProductosCodigo nchar(6),
ProductosDescripcion varchar(100),
ProductosPrecio Numeric(9,2),
ProductosStock Numeric(9,2),
ProductosEstado nchar(1),
ProductosFoto Image,
constraint ProductosPK primary key (ProductosCodigo)
)
go
Instrucción Update
Permite la actualización de los datos de los registros de las tablas.
Sintaxis
La forma de escribir la instrucción Update para SQL Server es como sigue:
Top n [Percent] Especifica los primeros registros que se actualizarán, puede expresarse en po
Tabla / Vista Nombre de la tabla o vista a actualizar. Puede incluir el servidor, el esquema
Set Permite especificar las columnas de la tabla o vista que se actualizarán. Las c
tiene Identity no se pueden actualizar.
Las columnas con restricciones Foreign Key, Check y Unique debe cumplir c
Where Especifica la condición o condiciones que debe de cumplir los registros para
Ejercicios
Usando Northwind
use Northwind
go
1. Cambiar la dirección del cliente Island Trading a “Av. Camino Real 3993”
2. Ver el resultado
Eliminación de Registros
Eliminar los registros de las tablas o vistas es una transacciones que debe
tenerse mucho cuidado en ejecutar.
Importante:
Es recomendable que los registros tengan una eliminación lógica, utilizar para
esto un campo para manejar el Estado del registro.
En ocasiones no se podrá eliminar los registros por restricciones de tipo Foreign
key. (Ver Cláves Foráneas)
En lo posible no implemente el borrado en cascada.
Puede usar transacciones para la eliminación física de registros para tener la
posibilidad de anular la eliminación si se comete algún error.
Puede usar Truncate con algún cuidado especial para eliminar todos los registros
de la tabla.
Recuerde que si se eliminan los registros en una tabla con un campo Identity, se
debe restablecer la propiedad al valor inicial.(Ver Post Propiedad Identity)
Si se eliminan los registros físicamente, se sugiere guardarlos en un historial. (Ver
Triggers – Historia de eliminados)
Sintaxis:
Delete
[ TOP ( expression ) [ PERCENT ] ]
[ FROM ] Tabla
[ WHERE <Condición> ]
Donde:
Top n [Percent] Especifica los primeros registros que se eliminarán, puede expresarse en
Ejercicios
Vamos a incluir algunos ejercicios, tenga cuidado con hacer estas pruebas,
posiblemente se elimine información útil.
Uso de Identity
By Trainer SQL in Registros - Vistas
Uso Identity
Identity es una propiedad que permite que un campo en una tabla incremente su
valor de manera automática al insertar los registros en ella.
Para el uso de la propiedad Identity el tipo de dato debe ser entero Int. Es
necesario definir un valor inicial y un valor de incremento.
Es importante anotar que Identity no asegura la unicidad de valor, esta
únicamente es posible con la restricciones Primary key, Unique o
con el índice Unique. Solamente puede existir una columna por tabla con la
propiedad Identidad.
Ejemplo
Insertar registros
insert into Personas (NombreCompleto)
values (‘Arturo Pérez’),(‘Fernando Sánchez’),(‘Antonio Ríos’),(‘José Campos’)
go
Listar los registros.
select * from Personas
go
Los registros anteriores toman los valores de Identidad del 1 al 4.
Para ver el valor de Indentity. Reporta Null si no se ha ingresado registros con
Identidad.
select @@IDENTITY
go
El listado se muestra
select * from Personas
go
Si se borran todos los registros
delete Personas
dbcc checkident (Personas, Reseed, 0)
go
Identity – Caso práctico
By Trainer SQL in Registros - Vistas
En este ejemplo se muestra como trabajar con la propiedad Identity y al borrar los
últimos registros resetear la propiedad para que los siguientes registros insertados
tengan el valor correcto correlativo. (Ver Uso de Identity)
— Insertar registros
insert into Datos (DatosDescripcion, DatosPrecio)
values (‘Casaca’,180),(‘Pantalón’,800),(‘Sombrero’,250)
go
select @@IDENTITY
go
delete Datos
go
DBCC CheckIdent (Datos, Reseed, 0)
go
— Insertar registros
Donde:
Ejercicios
Usando Northwind
use Northwind
go
Importante
En la definición de la consulta no se puede usar Order By salvo que se incluya
Top.
Todas las columnas de la definición de la vista deben tener nombre.
El select de la definición de la vista no puede tener la cláusula Into Tabla.
La vista puede tener hasta 1,024 columnas.
SQL Server permite la creación de secuencias que pueden ser utilizadas para la
generación de códigos en las tablas. Lo más importante de las secuencias es que
no están ligadas a ningún campo en una tabla. Se recomienda usar la opción de
Secuencias en lugar de usar la propiedad Identity, es necesario incidir en sugerir
adicionalmente que no use la propiedad Identity.
Un tipo de dato definido por el usuario creado en base a los tipos anteriores.
La propiedad Identity
Identity es una propiedad que permite que un campo en una tabla incremente su
valor de manera automática al insertar los registros en ella. Para el uso de la
propiedad Identity el tipo de dato debe ser entero Int. Es necesario definir un valor
inicial y un valor de incremento.
Donde
NombreDeSecuencia: es el nombre de la secuencia a crear.
TipoEntero: Tipo de dato entero de SQL Server. La tabla está definida líneas
arriba.
TipoEnteroDefinidoPorElUsuario: Tipo de dato definido por el usuario en base a
los números enteros de SQL Server. (Ver tipos de datos definidos por el usuario)
Start With: define el valor inicial
Increment by: Define el incremento o decremento.
MinValue: Especifica el valor mínimo, por defecto es CERO para el tipo tinyint y
un valor negativo para el resto de tipos.
MaxValue: Especifica el valor máximo. El valor por defecto está definido de
acuerdo al valor máximo del tipo de dato entero. (Ver tabla arriba)
Cycle: Permite que la secuencia se reinice cuando llega a su valor mínimo o
máximo, dependiendo si es ascendente o descendente.
Ejercicios
Usando la base de datos Northwind
USE Northwind
go
Para obtener el valor inicial de acuerdo al tipo de dato bigint. Tenga en cuenta que
al ejecutar la
siguiente instrucción, el valor de la secuencia se va incrementando 1. En la tabla
en la parte superior se puede visualizar el rango del tipo de dato binint.
Eliminar la secuencia
Drop sequence EquipoBasket
go
Usar la secuencia para obtener el valor para el código usando NEXT VALUE
FOR…
Insertar Departamentos
Consultar la tabla
Select * from Departamentos
go
Se sugiere crear algún algoritmo o código para generar un código que no sea
únicamente números.
Sintaxis:
Donde:
NombreDeSecuencia: es el nombre de la secuencia a modificar.
Restart With: define el valor en el que reiniciará la secuencia.
Increment by: Define el incremento o decremento.
MinValue: Especifica el valor mínimo, por defecto es CERO para el tipo tinyint y
un valor negativo para el resto de tipos.
MaxValue: Especifica el valor máximo. El valor por defecto está definido de
acuerdo al valor máximo del tipo de dato entero. (Ver tabla arriba)
Cycle: Permite que la secuencia se reinice cuando llega a su valor mínimo o
máximo, dependiendo si es ascendente o descendente.
Ejercicios
5. Crear una secuencia con valores por defecto y luego modificarla para que
su valor inicial sea 10 y se incremente de 5 en 5
Eliminar un secuencia
Instrucción Drop Sequence
Elimina una secuencia de la base de datos
Sintaxis:
Drop sequence [Esquema.]NombreSecuencia
Donde:
Esquema: es el nombre del esquema donde se encuentra la secuencia. (Ver
esquemas)
NombreSecuencia: nombre de la secuencia a eliminar.
Ejercicios
6. Eliminar la secuencia PruebaCambio
El usuario para que pueda mostrar los datos reales de la base de datos debe
actualiza la vista, para ello puede pulsar botón derecho en cualquier celda de la
vista y seleccionar Actualizar.
Usando Northwind
use Northwind
go
Crear una vista con los productos, su categoría y proveedor. (Ver Vistas)
Para poder mostrar los datos sin encriptar se utilizará Cast para convertir el tipo de dato.
(Ver funciones de conversión de datos)
Función EncryptByPassPhrase
Permite encriptar datos, asignando una clave de tipo texto.
Sintaxis:
EncryptByPassPhrase ( ‘FraseClave’ , ‘TextoAEncriptar’ )
Donde:
FraseClave: se utilizará como clave simétrica para poder desencriptar.
TextoAEncriptar: Texto plano a encriptar.
Función DecryptByPassPhrase
Permite desencriptar datos, es necesario dar la clave simétrica asignada al momento de
encriptar.
Sintaxis:
DecryptByPassPhrase ( ‘FraseClave’ , ‘TextoADesencriptar’ )
Donde:
FraseClave: es clave simétrica utilizada al encriptar.
TextoADesencriptar: Texto a desencriptar, generalmente es el contenido de un campo.
Importante: Los campos donde se guardarán los datos deben ser de tipo binarios
(varbinary).
Ejemplo
Usando la base de datos Northwind.
use Northwind
go
Crear una tabla para usuarios, donde se encriptará tanto el nombre del usuario como
su password.
select UsuariosCodigo,
Cast(DecryptByPassPhrase(‘ClaveUsuarios’, UsuariosNombre) As varchar(max)) As
‘Nombre’,
Cast(DecryptByPassPhrase(‘ClaveUsuarios’, UsuariosPassword) As varchar(200)) As
‘Password’
from Usuarios
go
Si el texto usado como clave simétrica no es el correcto, muestra Null en los campos
encriptados. Note que para desencriptar se ha utilizado la clave simétrica OtraClave, que
no la correcta.
select UsuariosCodigo,
Cast(DecryptByPassPhrase(‘OtraClave‘, UsuariosNombre) As varchar(max)) As
‘Nombre’,
Cast(DecryptByPassPhrase(‘OtraClave‘, UsuariosPassword) As varchar(200)) As
‘Password’
from Usuarios
go
Cursores
By Trainer SQL in Programación
Proceso para declarar, abrir, usar, cerrar y liberar los datos de un cursor
1. Declarar el cursor, utilizando DECLARE Cursor
2. Abrir el cursor, utilizando OPEN
3. Leer los datos del cursor, utilizando FETCH … INTO
4. Cerrar el cursor, utilizando CLOSE
5. Liberar el cursor, utilizando DEALLOCATE
2. Abrir el cursor
OPEN NombreDelCursor
3. Lectura de los datos del cursor, va a depender del tipo de cursor. Hay de
avance hacia adelante solamente y Scroll.
FETCH NombreDelCursor
BEGIN
4. Cerrar el cursor
CLOSE NombreDelCursor
DEALLOCATE NombreDelCursor
Ejercicios
1. Cursor que reporta los Empleados
select @@FETCH_STATUS
go
— Cerrar el cursor, liberar de memoria
close cursorEmpleados
Deallocate cursorEmpleados
go
Open cursorCategorias
go
Open cursorCategoriasListadoProductos
Declare @CodigoCategoria int, @NombreCategoria nvarchar(15)
Fetch cursorCategoriasListadoProductos into @CodigoCategoria,
@NombreCategoria
Print
‘============================================================’
Print ‘============ Listado de Productos por categoria ==========’
Print
‘============================================================’
Print ”
Begin
Begin
Print ”
Close cursorProductosCategoria
Deallocate cursorProductosCategoria
Close cursorCategoriasListadoProductos
Deallocate cursorCategoriasListadoProductos
go
Print ‘=====================================’
Print ‘=====PRODUCTOS POR CATEGORIA=========’
Print ‘=====================================’
While (@@FETCH_STATUS = 0)
Begin
Print ‘Código Categoria: ‘ + Ltrim(Str(@CodigoCategoria))
Print ‘Nombre Categoria: ‘ + Ltrim(@NombreCategoria)
Print ‘===================================================’
— Definir el cursor para los productos de la categoria actual
Declare cursorProductoPorCategoria cursor for
select ProductID, ProductName, UnitPrice, UnitsInStock from Products
where CategoryID = @CodigoCategoria
Open cursorProductoPorCategoria
Declare @CodigoProducto Integer, @NombreProducto nvarchar(40), @Precio
Numeric(9,2), @Stock Numeric(9,2)
Fetch cursorProductoPorCategoria into @CodigoProducto, @NombreProducto,
@Precio, @Stock
Close cursorProductoPorCategoria
Deallocate cursorProductoPorCategoria
Print ”
— Acumulado Total
Set @CantidadTotaldeProductos = @CantidadTotaldeProductos +
@CantidadProductosPorCategoria
Set @ValorTotaldelStock = @ValorTotaldelStock + @ValorStockPorCategoria
Close cursorCategorias
Deallocate cursorCategorias
go
Cursores
Elemento que almacena en memoria el resultado de un Select. Para mayor
información ver Cursores en SQL Server
Pasos:
1. Declarar el cursor, utilizando DECLARE
2. Abrir el cursor, utilizando OPEN
3. Leer los datos del cursor, utilizando FETCH … INTO
4. Cerrar el cursor, utilizando CLOSE
5. Liberar el cursor, utilizando DEALLOCATE
OPEN <NOMBRE_CURSOR>
WHILE (@@FETCH_STATUS = 0)
BEGIN
FETCH <NOMBRE_CURSOR> INTO <LISTA_VARIABLES>
…
END — FIN DEL BUCLE WHILE
CLOSE <NOMBRE_CURSOR>
DEALLOCATE <NOMBRE_CURSOR>
Ejercicios
Cursor que liste las categorias, el resultado se muestra como sigue:
1 Beverages
2 Condiments
3 Confections
4 Dairy Products
5 Grains/Cereals
6 Meat/Poultry
7 Produce
8 Seafood */
CURSORES ANIDADOS
Cursor que muestre las categorías y de cada categoría los productos
Cursor Scroll:
Para leer los datos del cursor definido como Scroll, en la instrucción Fetch se
puede usar las siguientes palabras para desplazarse.
— Último
Fetch Last from cursorScrollCategorias
go
— Retroceder 3
Fetch Relative -3 from cursorScrollCategorias
go
— Al número 6
Fetch Absolute 6 from cursorScrollCategorias
go
— Siguiente
Fetch next from cursorScrollCategorias
go
— Anterior
Fetch prior from cursorScrollCategorias
go
— Cerrar y liberar
Close cursorScrollCategorias
Deallocate cursorScrollCategorias
go
Triggers – Como crear un historial de
registros eliminados en SQL Server
By Trainer SQL in Esquemas - Tablas, Programación, Registros - Vistas
Eliminación de registros
La eliminación de registros de una tabla se puede hacer usando la instrucción
Delete (Ver Eliminación de registros), lo que en ocasiones no pueda ejecutarse
debido a restricciones de tipo Foreign Key (Ver Claves
Foráneas).
Un registro eliminado con Delete es imposible de recuperar, se recomienda el
borrado lógico, es decir, usando un campo que puede ser de tipo caracter donde
se pueda guardar datos como A de Activo y E de Eliminado.
USE Northwind
go
CREATE TABLE dbo.ProductosHistorialEliminados
(
ProductID int NOT NULL,
ProductName nvarchar(40) NOT NULL,
SupplierID int NULL,
CategoryID int NULL,
QuantityPerUnit nvarchar(20) NULL,
UnitPrice money ,
UnitsInStock smallint ,
UnitsOnOrder smallint ,
ReorderLevel smallint ,
Discontinued bit ,
FechaEliminacion Datetime
)
go
Note que se ha incluido un campo para la fecha de eliminación del tipo DateTime
para guardar el momento exacto de la eliminación. Puede guardar el usuario, el
equipo y algunos datos posiblemente necesarios. (Ver Triggers DDL)
El Trigger que va a guardar los datos del registro eliminado usando Delete en la
tabla Historial de Productos será como sigue
Eliminar registros
Primero intentaremos eliminar productos que tienen registros en detalle de
venta, por ejemplo, el registro con código 10.
Eliminar uno de los productos insertados, los que no figuran con clave foránea.
Según los registros insertados líneas arriba son los que tiene código 78, 79 y 80
Notas importantes
Se sugiere evitar los campos con la propiedad Identity (Ver Identity)
Se recomienda para almacenar los datos numéricos el uso de Numeric. (Ver Crear
tablas)
En ocasiones se pueden usar campos que especifiquen que los registros no se pueden
eliminar debido a que son de sistema.
Se sugiere con por ningún motivo se implemente el borrado en cascada.
Cursores con variables tipo tabla
By Trainer SQL in Programación
Ejercicios
Usando Northwind
use Northwind
go
Funciones de Cursor
Las funciones de cursor devuelven información de los cursores. (Ver cursores)
Función @Cursor_rows
Devuelve el número de filas del cursor abierto.
-1 El cursor es dinámico. Como los cursores dinámicos reflejan todos los cambio
cambia constantemente. Nunca se puede afirmar que se han recuperado todas l
0 No se han abierto cursores, no hay filas calificadas para el último cursor abiert
cancelado.
Ejemplo
— Crear un cursor para mostrar los Empleados
Declare cursorEmpleados Cursor for
select E.EmployeeID As ‘Código’, Empleado = E.LastName + Space(1)+
E.FirstName from Employees As E order by Empleado
Open cursorEmpleados
Fetch from cursorEmpleados
Print ‘========= EMPLEADOS ============= ‘
While @@FETCH_STATUS = 0
Begin
Fetch from cursorEmpleados
End
Close cursorEmpleados
Deallocate cursorEmpleados
go
Función Cursor_Status
Permite determinar si el resultado de un procedimiento almacenado ha devuelto
un cursor y un conjunto de resultados al recibir un parámetro.
Valor Descripción
Ejemplo
Crear un cursor con las categorías
Antes de Crear el cursor
select CURSOR_STATUS (‘global’,’cursorCategorias’) As ‘Antes de Crear’
go
Resultado: -3
Triggers
By Trainer SQL in Programación
Triggers
Un desencadenador o Trigger es una clase de procedimiento almacenado que se
ejecuta automáticamente cuando se realiza una transacción en la bases de datos.
Tipos de Triggers
Existen los siguientes tipos de Triggers
1. Los Triggers DML se ejecutan cuando se realizan operaciones de manipulación
de datos (DML). Los eventos DML son instrucciones INSERT, UPDATE o
DELETE realizados en una tabla o vista.
2. Los Triggers DDL se ejecutan al realizar eventos de lenguaje de definición de
datos (DDL). Estos eventos corresponden a instrucciones CREATE, ALTER y
DROP.
3. Los Triggers Logon, que se disparan al ejecutarse un inicio de sesión en SQL
Server.
Consideraciones
Una tabla puede tener un máximo de tres triggers: uno de actualización, uno de
inserción y uno de eliminación.
Cada trigger puede aplicarse a una sola tabla o vista. Por otro lado, un mismo
trigger se puede aplicar a las tres acciones: UPDATE, INSERT y DELETE.
No se puede crear un trigger en una vista ni en una tabla temporal, pero el trigger
puede hacer referencia a estos objetos.
Los trigger no se permiten en las tablas del sistema.
Note que para una operación de actualización, las dos tablas pueden ser
utilizadas.
Ejercicios
Usando Northwind
use Northwind
go
Insertar Categorias
Trigger de Inserción
5. Crear un Trigger que permita comprobar que se inserta una categoría con
nombre diferente. La tabla Inserted será utilizada para comprobar si ya hay
una categoría con el mismo nombre que la insertada.
Create trigger trCategoriaInsertaSinRepetidos ON Categories For Insert
AS
IF (Select COUNT (*) From Inserted, Categories
WHERE Inserted.CategoryName = Categories.CategoryName) >1
BEGIN
Rollback Transaction
PRINT ‘El Nombre de la Categoria ya existe…’
END
ELSE
PRINT ‘Categoría ingresada a la Base de datos’
go
Trigger Instead Of
Realizar acciones después de las instrucciones de un procedimiento o las
escritas directamente por el usuario. (Ver Triggers Instead Of)
Triggers Instead Of en SQL Server
By Trainer SQL in Consultas, Programación, Registros - Vistas
Notas importantes
1. Estos tipos de triggers cancelan la instrucción que hace que se dispare,
reemplazando
esta por las instrucciones del Trigger.
2. Generalmente se utilizan estos triggers en vistas
3. Las acciones que realice el trigger no deben cancelar la transacción que la
dispara sino ejecutar las instrucciones cambiadas que son el cuerpo del trigger.
Ejemplo
Usando la base de datos Northwind
use Northwind
go
Insertar un Cliente
Insertar un Proveedor
Note que al insertar registros en la vista debemos especificar todos los campos,
en el Trigger para los proveedores no se especifica el código porque es un campo
entero y es Identidad. (Ver Identity)
Triggers – Creando un historial
By Trainer SQL in Programación
En HistorialShippers
select * from HistorialShippers
go
Puede notarse que no hay registros.
Puede observar que la tabla HistorialShippers tiene los datos de los registros que
se insertaron o que se actualizaron.
Puede interesar
Triggers, definición y creación
Triggers DML encriptados
Triggers Logon
Triggers, activar y desactivar.
Ejemplos
Usando la base de datos Northwind
use Northwind
go
Para poder crear tablas, se debe eliminar el Trigger o solamente desactivar (Ver
Triggers Activar – Desactivar)
disable trigger trNoCrearModificarBorrarTablas on Database
go
2. Crear un Trigger que se dispare cuando se crea una vista y capture el evento
creado.
Para que el Trigger se dispare, crear un procedimiento almacenado para listar los
clientes
Borrar el SP
Procedimientos Almacenados
By Trainer SQL in Programación
Procedimientos Almacenados
Un procedimiento almacenado son instrucciones T-SQL almacenadas con un
nombre en la base de datos.
Mayor seguridad
Se pueden ejecutar SP con instrucciones que hacen referencia a objetos que los
usuarios no tienen permisos. El procedimiento realiza la ejecución del código y
todas las instrucciones y controla el acceso a los objetos a los que hace
referencia. Esto hace mas sencillo la asignación de permisos. Se puede
implementar la suplantación de usuarios usando Exexute As. Existe un nivel
fuerte de encapsulamiento.
Tráfico de red reducido
Un SP se ejecuta en un único lote de código. Esto reduce el tráfico de red cliente
servidor porque únicamente se envía a través de la red la llamada que ejecuta el
SP. La encapsulación del código del SP permite que viaje a través de la red como
un solo bloque.
Rendimiento mejorado
Los procedimientos almacenados se compila la primera vez que se ejecutan y
crean un plan de ejecución que vuelve a usarse en posteriores ejecuciones.
Tipos de procedimientos
Definidos por el usuario
Se crea por el usuario en las bases de datos definidas por el usuario o en las de
sistema (Master, Tempdb, Model y MSDB)
Sintaxis
Para crear un procedimiento almacenado se utiliza
Create procedure NombreProcedimiento
(
@PrimerParametro TipoDato,
@SegundoParametro TipoDato,…
)
As
Instrucciones del SP
go
Para modificar un SP
Alter procedure NombreProcedimiento
(
@PrimerParametro TipoDato,
@SegundoParametro TipoDato,… cambios
)
As
Instrucciones del SP con cambios
go
Eliminar un SP
Drop procedure NombreProcedimiento
go
Ejercicios
Use Northwind
go
Procedimientos Almacenados
Ejercicio para el uso de los procedimientos almacenados con los datos de una
tabla.
En este ejercicio se crea una tabla para carreras en la Universidad SQL, se crean
los procedimientos almacenados para insertar un registro, modificar los datos del
registro, listar los registros ordenados por descripción y borrar un registro.
Exec spCarrerasInsertarNuevo
@CarrerasVacantes =80 ,@CarrerasEstado =’A’,@CarrerasCodigo =’96325′,
@CarrerasDescripcion=’CONTABILIDAD’,@CarrerasAcreditada=’S’
go
Listado de Carreras
SELECT * FROM Carreras
go
Crear un Índice por Descripción de la carrera (Ver Índices)
create index CarrerasDescripcionIDXa on Carreras(CarrerasDescripcion)
with (fillfactor = 80)
go
Procedimientos para Listado, note que no aparecen los
que tienen en el estado la letra E que indica que han sido
eliminadas.
Create procedure spCarrerasListado
As
select CarrerasCodigo, CarrerasDescripcion, CarrerasAcreditada,
CarrerasVacantes, CarrerasEstado from Carreras
where CarrerasEstado <> ‘E’
order by CarrerasDescripcion
go
go
Merge
By Trainer SQL in Programación
Instrucción Merge
Realiza instrucciones de inserción de registros, actualización o eliminación de
registros en una tabla de destino en la misma base de datos o en otra base de
datos según los resultados de combinar los registros con una tabla de origen.
Sintaxis
La forma de usar Merge es la siguiente:
MERGE
[ TOP ( n ) [ PERCENT ] ]
[ INTO ] <Tabla_Destino> [ [ AS ] AliasTablaDestino ]
USING <Tabla_Origen> [ [ As ] AliasTablaOrigen]
ON <CondiciónMergeComparación>
[ WHEN MATCHED [ AND <Condición> ]
THEN <Isntrucción Si encuentra> ] [ …n ]
[ WHEN NOT MATCHED [ BY TARGET ] [ AND <Condición> ]
THEN <Instrucción Si NO Encuentra en Destino> ]
[ WHEN NOT MATCHED BY SOURCE [ AND <Condición> ]
THEN <Instrucción Si NO Encuentra en Origen> ] [ …n ]
Ejemplo
En este ejemplo, se tienen dos bases de datos cada una con una tabla de
Productos.
La base de datos Planes, con la tabla ProductosPlanes y la base de datos
Desarrollo con la tabla ProductosDesarrollo.
Haciendo el Merge
La tabla Origen es Productos de la base de datos Desarrollo y la tabla
Destino en Productos en la base de datos Planes
Procedimientos Almacenados con
parámetros de salida
By Trainer SQL in Consultas, Programación, Registros - Vistas
Parámetros
Los parámetros se usan para intercambiar datos entre las aplicaciones y los
procedimientos almacenados o la herramienta que ejecutó el procedimiento
almacenado.
Los parámetros de entrada permiten pasar un valor de datos al procedimiento
almacenado.
Los parámetros de salida permiten al procedimiento almacenado devolver un
valor
Los procedimientos almacenados devuelven un código de retorno de tipo entero.
El valor de retorno por defecto es CERO si no se establece explícitamente un
valor diferente
Ejemplos
Los siguientes ejemplos muestran como usar los parámetros de salida en
procedimientos almacenados.
Usando Northwind
use Northwind
go
Ejercicio 1
Procedimiento almacenado que reporta el número de productos de una
determinada categoría
Para ejecutar el procedimiento debemos crear antes una variable que permita
capturar el valor devuelto por el parámetro de salida del procedimiento.
Tomaremos como ejemplo la categoría 3.
Ejercicio 2
Procedimiento almacenado que reporta la cantidad de productos que es
necesario comprar con urgencia. (Productos cuyas Unidades en Stock es
menor a las unidades en Orden)
Para ejecutar el procedimiento debemos crear antes una variable que permita
capturar el
valor devuelto por el parámetro de salida del procedimiento.
Ejemplos
Ejercicio 01
En el siguiente ejemplo se va a crear una base de datos, en ella una tabla Ventas,
insertar registros con los datos de tres clientes de los cuales se han registrado
varias ventas. Luego se mostrará los resultados en columnas de acuerdo al
artículo vendido.
Ejercicio 02
with Ventas As (
select C.CompanyName As ‘Cliente’,
DATEPART(YY,O.OrderDate) As ‘Año’,
Sum(Od.UnitPrice * OD.Quantity) As ‘Importe’
from Customers as C
join Orders as O on C.CustomerID = O.CustomerID
join [Order Details] as OD on O.OrderID = OD.OrderID
group by C.CompanyName, DATEPART(YY,O.OrderDate))
select * from Ventas
pivot (Sum(Importe) for Año in ([1996],[1997],[1998])) PivotTable
— Columnas para los años 1996, 1997 y 1998 Pivot para los años
Ejercicio 03
with TotalOrdenes As (
Select Empleado = E.LastName + Space(1) + E.FirstName, YEAR(O.OrderDate)
As ‘Año’,
COUNT(O.OrderID) As ‘Órdenes’
from Employees As E
join Orders As O on E.EmployeeID = O.EmployeeID
Group by E.LastName + Space(1) + E.FirstName, YEAR(O.OrderDate) )
— El pivot
select * from TotalOrdenes
pivot (Sum(Órdenes) for Año in ([1996],[1997],[1998])) As Calculos
go
Common Table Expressions CTE
By Trainer SQL in Consultas, Funciones en SQL Server, Programación
Una CTE es similar a una tabla derivada (Ver tablas derivadas) en que no se
almacena como un objeto y dura sólo el tiempo que dura la consulta. A diferencia
de una tabla derivada, una CTE puede hacer referencia a sí misma y se puede
hacer referencia a ella varias veces en la misma consulta.
Ejercicios
Usando Northwind
use Northwind
go
Ejercicio 01
Mostrar los productos, su categoría y su proveedor. Mostrar los que no están
descontinuados ordenados por precio descendentemente. Para entender las
relaciones entre las tablas Ver Joins en SQL
— Usando CTE
— Asignando la CTE
with OrdenesEmpleados As
(select E.EmployeeID As ‘Codigo’, E.LastName As ‘Apellido’ ,
E.FirstName As ‘Nombre’, O.OrderID As ‘Nº Orden’,
Format(O.OrderDate,’dd/MMM/yyyy’) As ‘Fecha’
from Employees As E
join Orders As O on E.EmployeeID = O.EmployeeID)
select * from OrdenesEmpleados
go
with OrdenesEmpleados As
(select E.EmployeeID As ‘Codigo’, E.LastName As ‘Apellido’ ,
E.FirstName As ‘Nombre’, O.OrderID As ‘Nº Orden’,
Format(O.OrderDate,’dd/MMM/yyyy’) As ‘Fecha’
from Employees As E
join Orders As O on E.EmployeeID = O.EmployeeID)
Ejercicio 03
Mostrando los datos de una relación recursiva. En la tabla Empleados
(Employees) existe en campo ReportsTo que indica que un empleado debe
reportar su trabajo al que se indica en ese campo.
— Visualizar los datos
select E.EmployeeID, E.FirstName, E.LastName, E.ReportsTo from Employees As
E
go
with Jefe As
(select EmployeeID, LastName, FirstName from Employees)
Select J.EmployeeID As ‘Cód. Jefe’, [Empleado Jefe] = J.LastName + Space(1) +
J.FirstName,
E.EmployeeID As ‘Cód. Empleado’, Subordinado = E.LastName + Space(1) +
E.FirstName
from Jefe As J
join Employees As E on J.EmployeeID = E.ReportsTo
go