Logo UNLAM

BASE DE DATOS 2

Sección 1

Contenido de la sección 1.

BASE DE DATOS:

CREAR BASE DE DATOS (CREATE DATABASE)

                CREATE DATABASE test;
            

ELIMINAR BASE DE DATOS (DROP DATABASE)

                DROP DATABASE test;
            

Estructura de datos

INSERTAR EN UNA TABLA (INSERT INTO)

                INSERT INTO usuarios (usuario_id, nombre, apellido) 
                VALUES (8, 'María', 'López');
            

ACTUALIZAR TABLA (UPDATE)

                UPDATE usuarios SET edad = '21' WHERE usuario_id = 4;
                UPDATE usuarios SET edad = '20', init_date = '2020-10-12' WHERE usuario_id = 1;
            

ELIMINAR DE UNA TABLA (DELETE)

                DELETE FROM usuarios WHERE usuario_id = 6;
            

TABLAS

CREAR UNA TABLA (CREATE TABLE)

                CREATE TABLE persona (
                    id_persona INT PRIMARY KEY,
                    nombre VARCHAR(100),
                    apellido VARCHAR(100),
                    FOREIGN KEY (id_persona) REFERENCES usuarios(usuario_id)
                );
            

CAMBIAR UNA TABLA (ALTER TABLE)

                ALTER TABLE persona
                MODIFY COLUMN nombre VARCHAR(250); -- Cambiar el tipo de datos de un campo
                RENAME COLUMN apellido TO descripcion; -- Cambiar el nombre de un campo
                ADD COLUMN idpersona INT NOT NULL PRIMARY KEY; -- Agregar un nuevo campo
            

ELIMINAR UNA TABLA (DROP TABLE)

                DROP TABLE persona;
                DROP COLUMN descripcion;
            

SINTAXIS

                SELECT listaCampos
                [ INTO nuevaTabla ]
                FROM tablaOrigen
                [ WHERE condicionFiltro ]
                [ GROUP BY campoGrupo ]
                [ HAVING filtroGrupo ]
                [ ORDER BY campo/s [ ASC | DESC ] ]
            

SELECT

Permite seleccionar columnas específicas de una tabla.

SELECT nombre, edad FROM Personas;

LIKE

Busca coincidencias con patrones de texto usando comodines:

  • % coincide con varios caracteres
  • _ coincide con un solo carácter
SELECT * FROM Productos WHERE nombre LIKE 'C%';
Tipo de coincidencia Modelo Coincide No coincide
Varios caracteres 'a%a' 'aa', 'aBa', 'aBXBa' 'aBC'
Varios caracteres 'ab%' 'abcdefg', 'abc' 'cab', 'aab'
Un solo carácter 'a_a' 'aaa', 'a3a', 'aBa' 'aBBBa'
Un solo dígito 'a[0-9]a' 'a0a', 'a1a', 'a2a' 'aaa', 'a10a'
Rango de caracteres '[a-z]' 'f', 'p', 'j' '2', '&'
Fuera de un rango '[^a-z]' '9', '&', '%' 'b', 'a'
Distinto de un dígito '[!0-9]' 'A', 'a', '&', '~' '0', '1', '9'
Combinada 'a[^b-m]#' 'An9', 'az0', 'a99' 'abc', 'aj0'

BETWEEN

El operador BETWEEN se utiliza para filtrar valores dentro de un rango determinado (inclusive). Funciona con números, fechas o texto.

  SELECT * FROM tabla
  WHERE columna BETWEEN valor1 AND valor2;

BACKUP Y RESTORE

Son operaciones de mantenimiento o administración de bases de datos,backup hace una copia de seguridad de la base de datos para proteger los datos y restore restaura una base de datos a partir de un backup previo.

BACKUP DATABASE NombreDeLaBase
TO DISK = 'C:\Backups\NombreDeLaBase.bak';

RESTORE DATABASE NombreDeLaBase
FROM DISK = 'C:\Backups\NombreDeLaBase.bak';

Funciones de Agregado

Operan sobre conjuntos de datos:

COUNT

SELECT COUNT(*) FROM Empleados;
    SELECT AVG(salario) FROM Empleados;

GROUP BY

Agrupa datos para usarlos con funciones de agregado.

SELECT departamento, AVG(salario) 
    FROM Empleados 
    GROUP BY departamento;

HAVING

Filtra resultados después de agrupar.

SELECT departamento, AVG(salario)
    FROM Empleados
    GROUP BY departamento
    HAVING AVG(salario) > 50000;

DISTINCT

Elimina duplicados en los resultados.

SELECT DISTINCT ciudad FROM Clientes;

TOP

Limita la cantidad de resultados.

SELECT TOP 5 * FROM Productos ORDER BY precio DESC;

CASE

SELECT 
  nombre,
  CASE 
    WHEN edad >= 18 THEN 'Adulto'
    ELSE 'Menor'
  END AS tipoPersona
FROM Persona;

BUCLES

IF, WHILE, FOR: se usan dentro de procedimientos almacenados (Stored Procedures)

IF

  DECLARE @edad INT = 20;

IF @edad >= 18
   PRINT 'Es mayor';
ELSE
   PRINT 'Es menor';

WHILE

  DECLARE @contador INT = 1;

WHILE @contador <= 5
BEGIN
   PRINT 'Contador: ' + CAST(@contador AS VARCHAR);
   SET @contador = @contador + 1;
END

FOR

No existe como palabra clave, pero se puede lograr algo similar con cursores:

DECLARE cursor_libros CURSOR FOR
SELECT titulo FROM Libro;

OPEN cursor_libros;
FETCH NEXT FROM cursor_libros INTO @titulo;

WHILE @@FETCH_STATUS = 0
BEGIN
   PRINT @titulo;
   FETCH NEXT FROM cursor_libros INTO @titulo;
END

CLOSE cursor_libros;
DEALLOCATE cursor_libros;

Tipos de JOIN en SQL

Ejemplos concretos de JOIN en SQL

Vamos a trabajar con estas dos tablas de ejemplo:

Tabla Empleados

idEmpleado nombre idDepto
1 Ana 10
2 Luis 20
3 Marta NULL

Tabla Departamentos

idDepto nombreDepto
10 Finanzas
20 Marketing
30 IT

Resultados según tipo de JOIN

JOIN Consulta Resultado esperado
INNER JOIN SELECT e.nombre, d.nombreDepto FROM Empleados e INNER JOIN Departamentos d ON e.idDepto = d.idDepto; Ana - Finanzas
Luis - Marketing
LEFT JOIN SELECT e.nombre, d.nombreDepto FROM Empleados e LEFT JOIN Departamentos d ON e.idDepto = d.idDepto; Ana - Finanzas
Luis - Marketing
Marta - NULL
RIGHT JOIN SELECT e.nombre, d.nombreDepto FROM Empleados e RIGHT JOIN Departamentos d ON e.idDepto = d.idDepto; Ana - Finanzas
Luis - Marketing
NULL - IT
FULL JOIN SELECT e.nombre, d.nombreDepto FROM Empleados e FULL JOIN Departamentos d ON e.idDepto = d.idDepto; Ana - Finanzas
Luis - Marketing
Marta - NULL
NULL - IT
CROSS JOIN SELECT e.nombre, d.nombreDepto FROM Empleados e CROSS JOIN Departamentos d; Ana - Finanzas
Ana - Marketing
Ana - IT
Luis - Finanzas
Luis - Marketing
Luis - IT
Marta - Finanzas
Marta - Marketing
Marta - IT

¿Qué hace cada tipo de JOIN?

✅ INNER JOIN

Trae solo los registros que coinciden en ambas tablas.

Ejemplo: Empleados con un departamento válido existente.

👈 LEFT JOIN

Trae todos los registros de la tabla izquierda, aunque no tengan coincidencia en la derecha.

Ejemplo: Todos los empleados, incluso los que no tienen departamento (depto será NULL).

👉 RIGHT JOIN

Trae todos los registros de la tabla derecha, aunque no tengan coincidencia en la izquierda.

Ejemplo: Todos los departamentos, incluso los que no tienen empleados.

🔄 FULL JOIN

Une todo de ambas tablas. Si no hay coincidencia, muestra NULL en lo que falta.

Ejemplo: Empleados y departamentos, aunque no estén relacionados.

🔢 CROSS JOIN

Crea todas las combinaciones posibles entre las filas de ambas tablas.

Ejemplo: 3 empleados y 3 departamentos = 9 combinaciones posibles.

Introducción a SQL Server

SQL Server es un sistema de gestión de bases de datos relacional (RDBMS) desarrollado por Microsoft. Se utiliza para almacenar y recuperar datos cuando lo requieren otras aplicaciones, ya sea en un entorno local o en la nube.

Es ideal para aplicaciones empresariales que requieren gestión robusta de datos, consultas avanzadas, y funcionalidades como transacciones, seguridad y replicación.

¿ QUE ES UN MOTOR DE BD?

Motor de BDD es el componente principal que se instala como un servicio en sistemas operativos para almacenar, procesar y proteger los datos. Proporciona acceso controlado y procesamiento rápido de transacciones para cumplir los requisitos de las aplicaciones consumidoras de datos más exigentes de la empresa.

¿Qué es Transact-SQL (T-SQL)?

  • Es el lenguaje de programación que se emplea para mandar peticiones entre el cliente y el servidor.
  • Es un lenguaje exclusivo de SQL Server, pero basado en el lenguaje SQL estándar (ANSI SQL), utilizado por casi todos los tipos de bases de datos relacionales que existen.
Tiene ventajas como:
  • Uso de variables y estructuras de control (IF, WHILE).
  • Creación de procedimientos almacenados, funciones y triggers.
  • Control de errores con TRY...CATCH.

Es el lenguaje que el cliente usa para enviar instrucciones al servidor SQL Server. Solo está disponible para este sistema.

              
          -- Ejemplo simple de T-SQL con variables
          DECLARE @Nombre NVARCHAR(50)
          SET @Nombre = 'Ana'
          
          SELECT * FROM Empleados WHERE nombre = @Nombre
              
            

Caracteristicas del SQL

SQL proporciona dos tipos de sentencias diferentes:

1.Especificar el esquema relacional: DDL(DATA DEFINITION LANGUAGE)

Las sentencias DDL permiten crear(CREATE), modificar(ALTER) y eliminar(DROP) objetos de la base de datos, como tablas, índices y Permisos(GRANT Y REVOKE)

2.Expresar las consultas y actualizaciones de la base de datos: DML(DATA MANIPULATION LANGUAGE)

Permite la recuperación de información (SELECT),Inserción de nueva información (INSERT),modificación de información almacenada (UPDATE),Eliminación (borrado) de información existente (DELETE)

DISEÑO DE LA BASE DE DATOS

  • Cuando se utiliza una base de datos para gestionar información, se está plasmando una parte del mundo real en una serie de tablas, registros y campos ubicados en una computadora, creándose un modelo parcial de la realidad.
  • Antes de crear físicamente estas tablas se debe realizar un modelo de datos, llamado de entidad-relación

ENTIDAD

  • Una entidad es cualquier "objeto" discreto sobre el que se tiene información.
  • Cada ejemplar de una entidad se denomina instancia.
  • Las entidades son modeladas en la base de datos como tablas.

RELACIÓN

  • Una relación describe cierta interdependencia (de cualquier tipo) entre una o más entidades.
  • Una relación no tiene sentido sin las entidades que relaciona.
  • Las relaciones son definidas con claves primarias y claves foráneas, manteniendo la integridad referencial.

CARNALIDAD DE LAS RELACIONES

  • Una relación describe cierta interdependencia (de cualquier tipo) entre una o más entidades.
  • Relaciones de uno a uno: una instancia de la entidad a se relaciona con una y solamente una de la entidad b.
  • Relaciones de uno a muchos: cada instancia de la entidad a se relaciona con varias instancias de la entidad b.
  • Relaciones de muchos a muchos: cualquier instancia de la entidad a se relaciona con cualquier instancia de la entidad b.

Relaciones y Claves Foráneas

En bases de datos relacionales, una relación define cómo se conectan los datos entre distintas tablas. Las relaciones más comunes son:

  • Uno a uno: Un registro de una tabla se relaciona con un solo registro de otra.
  • Uno a muchos: Un registro de una tabla puede estar relacionado con varios registros de otra (muy común).
  • Muchos a muchos: Requiere una tabla intermedia para unir ambas.

Una clave foránea (foreign key) es un campo que conecta dos tablas, asegurando la integridad referencial.

              
          -- Crear tabla Departamentos
          CREATE TABLE Departamentos (
            idDepto INT PRIMARY KEY,
            nombreDepto VARCHAR(50)
          )
          
          -- Crear tabla Empleados con clave foránea
          CREATE TABLE Empleados (
            idEmpleado INT PRIMARY KEY,
            nombre VARCHAR(50),
            idDepto INT FOREIGN KEY REFERENCES Departamentos(idDepto)
          )
              
            

ATRIBUTOS

  • Las entidades tienen atributos.
  • Un atributo de una entidad representa alguna propiedad
  • En el modelo de bases de datos, los atributos son almacenados como columnas o campos de una tabla.

MODELADO DE ELEMENTOS DE DATOS

  • SQL emplea tablas como objetos de almacenamiento de datos, que los usuarios manipulan a través de sus aplicaciones.
  • Las tablas son objetos compuestos por una estructura (conjunto de columnas) que almacenan información interrelacionada (filas) acerca de algún objeto en general.

MODELADO DE ELEMENTOS DE DATOS-CARACTERISTICAS

  • Las tablas tienen un solo nombre y es único en toda la base datos.
  • Están compuestas por registros y campos.
  • Los registros y campos pueden estar en diferentes órdenes.
  • Una base de datos contiene muchas tablas. cada tabla almacena información.

RESTRICCIONES

  • Los nombres de las tablas deben ser únicos en la base de datos.
  • Los nombres de las columnas deben ser únicos en la tabla.
  • No puede haber dos registros con el mismo valor de la clave primaria.(Primary key – pk – clave principal)

Dentro de las restricciones que podemos establecer desde el diseño de los campos, además del tipo de datos son:
NO ADMITA VALORES NULOS
NO ADMITA VALORES DUPLICADOS

CLAVE PRIMARIA (PRIMARY KEY)

  • Es un campo o un grupo de campos que fuerzan la integridad de los datos en la tabla, asegurándose que cada registro en la tabla es único.
  • Solo puede haber una sola clave primaria por tabla.
  • La clave primaria no permite valores nulos o duplicados.
  • Se crea un índice al definir una clave primaria.

CLAVE FORANEA (FOREIGN KEY)

  • Es un campo que permite establecer un vínculo entre las tablas, en general , se ubican en las tablas del lado de “muchos”, ya que este campo se puede repetir.

ACCESO A LAS BASES DE DATOS

El acceso para trabajar con las bases de datos, en nuestro caso sql sever, debemos,  ademas del motor, tener instalado un IDE para el manejo de los datos, nosotros tenemos instalado el sql server managment studio express ( gratuito) para sencillas aplicaciones y educación.

Para acceder al motor de sql y sus bases de datos existen 2 maneras:

  1. Con credenciales de Windows (S.O.): Este tipo de acceso se denomina “integrado con windows” o autenticacion de windows”, y no requiere usuario y password.
  2. Con credenciales de sql server: Este tipo de acceso se denomina autenticación de sql server ”, y requiere un usuario de sql registrado y una contraseña.

FORMAS NORMALES EN LAS BASES DE DATOS

La normalización de bases de datos es un proceso que consiste en designar y aplicar una serie de reglas a las relaciones obtenidas tras el paso del modelo entidad-relación al modelo relacional.

Es un proceso para organizar las tablas de una base de datos de forma lógica, dividiendo la información en partes más pequeñas y eliminando duplicaciones.

Las bases de datos relacionales se normalizan para:

  • Evitar la redundancia de los datos.
  • Disminuir problemas de actualización de los datos en las tablas.
  • Proteger la integridad de los datos.

Formas Normales (1FN, 2FN, 3FN)

La normalización es el proceso de organizar los datos en una base de datos para reducir la redundancia y mejorar la integridad de los datos. Las tres primeras formas normales (1FN, 2FN y 3FN) son las más comunes y suficientes en la mayoría de los casos.

📦 Primera Forma Normal (1FN)

  • Todos los atributos deben contener valores atómicos (un solo valor por celda).
  • No debe haber columnas con listas o grupos repetitivos.
  • Se encuentra en 1FN si todo atributo contiene un valor indivisible o atomico (ausencia de grupos repetitivos).

Ejemplo NO cumple 1FN:

ClienteTeléfonos
Ana1111, 2222
Juan3333, 4444, 5555

Ejemplo corregido (1FN cumplida):

ClienteTeléfono
Ana1111
Ana2222
Juan3333
Juan4444
Juan5555

✌️ Segunda Forma Normal (2FN)

  • Ya debe cumplir 1FN.
  • Todos los atributos no clave deben depender de toda la clave primaria.
  • Una tabla que está en la primera forma normal (1NF) debe satisfacer criterios adicionales para calificar para la segunda forma normal.
  • Específicamente: una tabla 1NF está en 2NF si y solo si, dada una clave primaria y cualquier campo que no sea un constituyente de la clave primaria, el campo NO clave depende de toda la clave primaria y no solo de una parte.

Ejemplo NO cumple 2FN:

ID_CursoID_AlumnoNombreAlumnoNombreCurso
1101AnaSQL Básico
1102JuanSQL Básico

Solución (dividir en dos tablas):

Cursos

ID_CursoNombreCurso
1SQL Básico

Alumnos_Curso

ID_CursoID_AlumnoNombreAlumno
1101Ana
1102Juan

🔺 Tercera Forma Normal (3FN)

  • Ya debe cumplir 2FN.
  • No debe haber dependencias transitivas (un atributo no clave no debe depender de otro no clave).

Ejemplo NO cumple 3FN:

ID_EmpleadoNombreID_DepartamentoNombreDepartamento
1Ana10Recursos Humanos

Solución (dividir en dos tablas):

Empleados

ID_EmpleadoNombreID_Departamento
1Ana10

Departamentos

ID_DepartamentoNombreDepartamento
10Recursos Humanos

🧠 Resumen de las Formas Normales

FormaQué evitaRegla principal
1FNValores múltiples por celdaSolo un valor por campo
2FNDependencia parcialTodos los campos dependen de toda la clave
3FNDependencia transitivaNingún campo no clave depende de otro no clave

Operadores Lógicos en SQL

Los operadores lógicos se usan en la cláusula WHERE para combinar condiciones.

  • AND: Devuelve resultados si todas las condiciones son verdaderas.
  • OR: Devuelve resultados si alguna condición es verdadera.
  • IN: Verifica si un valor está en una lista.
              
          -- Empleados que trabajan en los departamentos 1, 2 o 3
          SELECT * FROM Empleados WHERE idDepto IN (1, 2, 3)
          
          -- Empleados que se llaman Ana y están en el depto 2
          SELECT * FROM Empleados WHERE nombre = 'Ana' AND idDepto = 2
          
          -- Empleados que están en el depto 1 o se llaman Juan
          SELECT * FROM Empleados WHERE idDepto = 1 OR nombre = 'Juan'
              
            

Funciones en SQL Server

En SQL Server, una función es un bloque de código reutilizable que puede recibir parámetros y devolver un valor. Se utilizan para realizar cálculos o transformar datos.

Tipos de funciones

  • Funciones escalares: Devuelven un solo valor (por ejemplo: fecha, número, texto).
  • Funciones de agregado: Operan sobre un conjunto de filas y devuelven un único valor.
  • Funciones de sistema: Incluidas por SQL Server para tareas comunes.
  • Funciones definidas por el usuario (UDF): Creadas por el usuario.

Ejemplos comunes

              
          -- Función escalar: convierte a mayúsculas
          SELECT UPPER('hola mundo') -- Resultado: HOLA MUNDO
          
          -- Función de fecha: día actual
          SELECT GETDATE() -- Resultado: fecha y hora actual
          
          -- Función de agregado: suma total de sueldos
          SELECT SUM(sueldo) FROM Empleados
          
          -- Función definida por el usuario (ejemplo simple)
          CREATE FUNCTION dbo.SumarDosNumeros (@a INT, @b INT)
          RETURNS INT
          AS
          BEGIN
            RETURN @a + @b
          END
          
          -- Uso de función definida por el usuario
          SELECT dbo.SumarDosNumeros(5, 3) -- Resultado: 8
              
            

Las funciones son muy útiles para reutilizar lógica, realizar cálculos personalizados o limpiar datos dentro de consultas SQL.

Sección 2

Contenido de la sección 2.

Funciones avanzadas en SQL Server

En SQL Server existen diferentes tipos de funciones que permiten trabajar con números, fechas, cadenas y datos agrupados. A continuación, se detallan las más usadas con ejemplos.

Definición:

Funciones del sistema

Funciones definidas por el usuario (UDFs)

Funciones de Configuración

🔢 Funciones de agregado (devuelven un valor a partir de muchas filas)

Definicion de funcion de agregado:

📅 Conversión de tipos (funciones escalares)

Definicion de funcion escalar:

📅 Funciones de Fecha y Hora (SQL Server)

Estas funciones forman parte de las funciones escalares, ya que devuelven un solo valor. Permiten trabajar con fechas, extraer partes de ellas, modificarlas o convertirlas a texto.

✅ Obtener la fecha y hora actual

🕒 Extraer partes de una fecha

🔄 Modificar fechas

🔁 Conversión de fecha a texto

🧪 Ejemplo completo


            SELECT
              GETDATE() AS FechaActual,
              CAST(GETDATE() AS VARCHAR) AS FechaTexto,
              YEAR(GETDATE()) AS Anio,
              DATEADD(day, 30, GETDATE()) AS FechaEn30Dias,
              DATEDIFF(day, '2025-01-01', GETDATE()) AS DiasDesdeInicioAno;
              

🔠 Funciones de cadena (funciones escalares)

Sirven para manipular texto. Estas son muy comunes:

📚 Clasificación de funciones

Ejemplo de funcion definida por el usuario

Funciones de configuracion

Son funciones que devuelven valores relacionados con la configuración del sistema, del usuario o de la sesión actual.

Sección 3

Contenido de la sección 3.

Dos categorías de aplicaciones de BD

Base de Datos del Sistema

Estas bases vienen preinstaladas con SQL Server y son cruciales para su funcionamiento interno. No son creadas por el usuario, y cada una cumple un rol específico:

Vistas del Catalogo

Todos los metadatos del catálogo disponiblespara el usuario se exponen mediante las vistas de catálogo. Las vistas de catálogo de SQL Server se han organizado en varias categorías.

FUNCIONES DEL SISTEMA

Devuelven información acerca de la base de datos y de los objetos de la misma. Solo se mencionan algunas de ellas:

DB_ID:Devuelve el número de identificación (Id.) de esa base de datos. SELECT DB_ID('master') Devuelve 1

DB_NAME:Devuelve el nombre de la base de datos.SELECT DB_NAME(1) Devuelve master

FILE_ID:Devuelve el número de identificación del archivo (Id.) del nombre de archivo lógico dado de la base de datosactual.SELECT FILE_ID('AdventureWorks_Data') Devuelve 1

FILE_NAME:Devuelve el nombre del archivo lógico dado de la base de datos actual.SELECT FILE_NAME(1) Devuelve AdventureWorks_Data

Procedimientos Almacenados de Sistema

Estos son algunos de los procedimientos almacenados de sistema que permiten consultar información sobre base de datos: Sp_Databases: Lista las bases de datos disponibles de un Server Sp_Databases

Sp_HelpDB:Información sobre las bases de datos de un servidor

Sp_Help:Presenta información acerca de un objeto de base de datos(cualquier objeto de la vista de compatibilidad sys.sysobjects), un tipo de datos definido por el usuario o un tipo de datos. Puede ejecutarse sin parámetros, entonces muestra la información sobre todos los objetos o puede pasarse como parámetro el nombre del objeto a consultar.

GRUPOS DE ARCHIVOS

Son parte de la estructura física de la base de datos.
Las bases de datos de SQL Server utilizan tres tipos de archivos:

Archivos de datos principales:Es el punto de partida de la base de datos y apunta a los otros archivos de la base de datos. Cada base de datos tiene un archivo de datos principal. La extensión recomendada para los nombres de archivos de datos principales es .mdf.

Archivos de datos secundarios:Son todos los archivos de datos menos el archivo de datos principal.Puede que algunas bases de datos no tengan archivos de datos secundarios, mientras que otras pueden tener varios archivos de datos secundarios. La extensión de nombre de archivo recomendada para los archivos de datos secundarios es .ndf.

Archivos de registro:almacenan toda la información de registroque se utiliza para recuperar la base de datos. Como mínimo, tiene que haber un archivo de registro por cada base de datos, aunque puede haber varios. La extensión de nombre de archivo recomendada para los archivos de registro es .ldf.

SQL Server no exige las extensiones de nombre de archivo .mdf, .ndf y .ldf, pero estas extensiones ayudan a identificar las distintas clases de archivos y su uso.

ESQUEMAS (SCHEMAS)

Definición: Es un espacio de nombres (namespace) distintoque existe de forma independientemente del usuario de base de datos que lo creó. Es un contenedor de objetos. Cualquier usuario puede ser propietario de un esquema, y esta propiedad es transferible. Todas las bases de datos contienen un esquema llamado dbo. Es el esquema predeterminado para todos los usuarios cuando no se define explícitamente el esquema. Ejemplo: CREATE SCHEMA Ventas

Ventajas

Instantáneas de Base de Datos

Tipos de restricciones

Sección 4

Contenido de la sección 4.

Argumentos

Parámetros de creación de base de datos:

Opciones de BD

Opciones de configuración de la base de datos:

Sección 5

Contenido de la sección 5.

Indices

Un índice es una estructura que acelera la búsqueda de datos en una tabla, similar a cómo un índice de un libro te ayuda a encontrar temas rápidamente.

SQL Server accede a los datos de dos maneras:

  1. recorriendo las tablas;comenzando el principio y extrayendo los registros que cumplen las condiciones de la consulta.
  2. empleando índices; recorriendo la estructura de árbol del índice para localizar los registros y extrayendo los que cumplen las condiciones de la consulta.

La desventaja es que consume espacio en disco y genera costo de mantenimiento (tiempo y recursos).
Los índices más adecuados son aquellos creados con campos que contienen valores únicos.
Es importante identificar el o los campos por los que sería útil crear un índice, aquellos campos por los cuales se realizan búsqueda con frecuencia: claves primarias, claves externas o campos que combinan tablas.
No se recomienda crear índices por campos que no se usan con frecuencia en consultas o no contienen valores únicos.

SQL Server permite crear 2 tipos de índices:

  • Create a single nonclustered index
  • CREATE UNIQUE NONCLUSTERED INDEX IX_NC_PresidentNumber ON dbo.Presidents (PresidentNumber) -- specify table and column name

    a

    Sección 6

    Contenido de la sección 6.

    Vistas(Views)

    Las vistas Permiten

    1. Ocultar información: Permitiendo el acceso a algunos datos y manteniendo oculto el resto de la información que no se incluye en la vista. El usuario opera con los datos de una vista como si se tratara de una tabla, pudiendo modificar tales datos.
    2. Simplificar la administración de los permisos de usuario: Se pueden dar al usuario permisos para que solamente pueda acceder a los datos a través de vistas, en lugar de concederle permisos para acceder a ciertos campos, así se protegen las tablas base de cambios en su estructura.

    VENTAJAS DE VISTAS

    DEFINICION DE VISTAS

    Creacion de vistas

    Supongamos que tenés una tabla Empleados y querés crear una vista que muestre solo a los empleados con sueldo mayor a $3000.

      CREATE VIEW Vista_EmpleadosActivos
      AS
      SELECT Nombre, Edad, Sueldo
      FROM Empleados
      WHERE Sueldo > 3000;
    

    Nota:Cualquier tabla se puede crear una vista.
    No se puede incluir la cláusula ORDER BY.
    No se puede incluir la palabra clave INTO.
    No se puede incluir la palabra clave INTO

    Modificacion de vistas

    Si querés cambiar la definición de una vista existente, usás ALTER VIEW

    Por ejemplo, ahora querés que también muestre la fecha de ingreso:

      ALTER VIEW Vista_EmpleadosActivos
      AS
      SELECT Nombre, Edad, Sueldo, FechaIngreso
      FROM Empleados
      WHERE Sueldo > 3000;
    

    Nota:Alteración de vistas.
    Hace que la instrucción SELECT y las opciones reemplacen la definición existente.
    No pueden afectar a más de una tabla subyacente.
    No pueden afectar a ciertas columnas.
    Pueden provocar errores si afectan a columnas a las que la vista no hace referencia.
    Consideraciones acerca del rendimiento.
    Uso de vistas para dividir datos.
    Conserva los permisos asignados.

    Modificacion de datos en las vistas

    Eliminar vista

    Para eliminarla completamente:

      DROP VIEW Vista_EmpleadosActivos;
    

    Nota:Esto borra la vista de la base de datos. Si después intentás hacer un SELECT * FROM Vista_EmpleadosActivos, te va a dar error.

    🔧 Optimización del rendimiento mediante vistas

    Las vistas pueden ayudar a mejorar el rendimiento de consultas frecuentes al encapsular lógica compleja en una estructura reutilizable. Aunque no almacenan datos, SQL Server puede optimizar el uso de vistas en ciertas condiciones.

    🔐 Otorgar permisos sobre vistas

    En lugar de dar acceso directo a las tablas base, podés controlar el acceso de los usuarios usando vistas.

    Ejemplo:

    -- Otorgar permiso de lectura sobre una vista específica
    GRANT SELECT ON Vista_EmpleadosPublicos TO usuarioX;
    
    -- Otorgar permiso a un rol (por ejemplo, 'Vendedores')
    GRANT SELECT ON PedidosAlfki TO Vendedores;
    

    Restricciones

    🚫 Uso de WITH CHECK OPTION en vistas

    La cláusula WITH CHECK OPTION se usa en la creación de vistas para asegurar que toda operación de inserción o actualización hecha a través de la vista respete la condición definida en la misma.

    Ejemplo sin restricción:

    CREATE VIEW Vista_EmpleadosBienPagos AS
    SELECT * FROM Empleados
    WHERE Sueldo >= 3000;
    

    Permite insertar empleados con sueldo menor a 3000, pero luego no se verán en la vista.

    Ejemplo con restricción:

    CREATE VIEW Vista_EmpleadosBienPagos AS
    SELECT * FROM Empleados
    WHERE Sueldo >= 3000
    WITH CHECK OPTION;
    

    Evita insertar o actualizar registros que no cumplan la condición de la vista.

    Tema segundo parcial

    Variables en SQL Server

    Declaración:

    Una variable local se declara así:DECLARE @NOMBREVARIABLE TIPO

    Ejemplo: DECLARE @nombre varchar(20)

    Procedimientos almacenados

    Caracteristicas

    Ventajas

    Creacion de Procedimientos

    Se puede usar el comando CREATE PROCEDURE, o su versión abreviada, CREATE PROC, para crear un procedimiento almacenado en el Query.

      CREATE PROC [ EDURE ] procedure_name [ ; number ] 
        [ { @parameter data_type } 
            [ VARYING ] [ = default ] [ OUTPUT ] 
        ] [ ,...n ] 
    
      [ WITH 
        { RECOMPILE | ENCRYPTION | RECOMPILE , ENCRYPTION } ]
    

    Si se especifica RECOMPILE no se podrá cachear el procedimiento y el mismo será recompilada cada vez que se utilice

    ENCRYPTION: Encriptar el contenido del procedimiento almacenado por razones de seguridad.

    Ejemplo:

      CREATE PROC Production.LongLeadProducts
      AS
      SELECT Name, ProductNumber
      FROM Production.Product
      WHERE DaysToManufacture >= 1
      GO
    

    Este código creará un procedimiento llamado LongLeadProducts dentro del esquema Production.

    Llamadas a Procedimientos

    Si el procedimiento almacenado no es el primer comando en un batch, para ejecutarlo se debe preceder el nombre del procedimiento con las palabras claves EXECUTE o EXEC. Ejemplo muestra cómo llamar al procedimiento LongLeadProducts:
    EXEC Production.LongLeadProducts

    Modificando Procedimientos

    Los Procedimientos a menudo deben ser modificados en respuesta a requerimientos del usuario o cambios en las definiciones de las tablas involucradas. Para modificar un Procedimiento, reteniendo los permisos asignados, use la sentencia ALTER PROCEDURE. Modifica un solo Procedimiento, si este llama a otros procedimientos, estos últimos no resultan modificados.

    Ejemplo:

      ALTER PROC Production.LongLeadProducts
      AS
      SELECT Name, ProductNumber, DaysToManufacture
      FROM Production.Product
      WHERE DaysToManufacture >= 1
      ORDER BY DaysToManufacture DESC, Name
      GO
    

    Eliminar Procedimientos

    Parámetros

    Procedimientos con Parámetros

    Ejemplo:

      CREATE PROC Production.LongLeadProducts( @dias int )
      AS
      SELECT Name, ProductNumber
      FROM Production.Product
      WHERE DaysToManufacture >= @dias
            
      Ejemplo de un procedimiento con más de un parámetro:
      CREATE PROC Production.LongLeadProducts( @dias_desde int, @dias_hasta int )
      AS
      SELECT Name, ProductNumber
      FROM Production.Product
      WHERE DaysToManufacture BETWEEN @dias_desde AND @dias_hasta
    

    Creación del SP

      CREATE PROCEDURE proc_producto
      @n1 smallint,
      @n2 smallint,
      @resultado smallint OUTPUT
      AS
      SET @resultado = @n1* @n2
    

    Ejecución del SP

      DECLARE @resp smallint
      EXECUTE proc_producto 5, 6, @resp OUTPUT
      SELECT 'El resultado es: ' , @resp 
    

    Resultados del SP

      El resultado es : 30
    

    Manejo de Errores con SQL

    TRY – CATCH

    Sintaxis

      BEGIN TRY
         { sql_statement | statement_block }
      END TRY
      BEGIN CATCH
         { sql_statement | statement_block }
      END CATCH
    

    Ejemplo:

      USE AdventureWorks2014
    
      BEGIN TRY
      -- Generate a divide-by-zero error  
      SELECT
        1 / 0 AS Error;
      END TRY
      BEGIN CATCH
        SELECT
          ERROR_NUMBER() AS ErrorNumber,
          ERROR_STATE() AS ErrorState,
          ERROR_SEVERITY() AS ErrorSeverity,
          ERROR_PROCEDURE() AS ErrorProcedure,
          ERROR_LINE() AS ErrorLine,
          ERROR_MESSAGE() AS ErrorMessage;
      END CATCH;
      GO
    

    Funciones definidas por el usuario

    Tipos de Funciones

    SQL Server provee diferentes tipos de funciones:

    Funciones Escalares Funciones Tabulares En Línea Funciones Tabulares Multi-sentencia
    • Devuelven un solo valor del tipo definido en la cláusula RETURNS.
    • Este tipo de funciones es sintácticamente similar a las funciones del Sistema tales como COUNT() o MAX().
    • Devuelven una tabla que es el resultado de una sola sentencia SELECT.
    • Es similar a una Vista, pero ofrecen más flexibilidad que una Vista porque se le pueden suministrar parámetros a la Función.
    • Devuelve una Tabla construida por una o más sentencias Transact-SQL.
    • Es similar a un Procedimiento Almacenado, pero a diferencia de este último, la Vista puede referenciarse en la cláusula FROM de una sentencia SELECT como si se tratase de una Tabla.
    NOTA:El cuerpo de la Función es definido por un bloque BEGIN…END , contiene las sentencias Transact-SQL que devuelven el valor.

    Ejemplo funcion escalar:

      CREATE FUNCTION Sales.SumSold(@ProductID int) RETURNS int  
      AS  
      BEGIN 
        DECLARE @ret int 
        SELECT @ret = SUM(OrderQty)  
        FROM Sales.SalesOrderDetail WHERE ProductID = @ProductID  
        IF (@ret IS NULL)  
          SET @ret = 0 
        RETURN @ret 
      END 
    

    Para modificar o eliminar una Función. Use ALTER FUNCTION para modificar sus funciones. Luego de creadas, use DROP FUNCTION para eliminar Funciones de la base de datos.
    Una Función Escalar puede ser invocada en cualquier lugar del código dónde se necesite una expresión del mismo tipo de datos.
    El siguiente ejemplo, hace un SELECT que recupera ProductID, Name, y el resultado de la función escalar llamada SumSold para cada producto en la base AdventureWorks.
    SELECT ProductID, Name, Sales.SumSold(ProductID) AS SumSold
    FROM Production.Product

    Funciones Tabulares En Línea:Podemos usar Funciones Tabulares En Línea para obtener la funcionalidad de Vistas parametrizadas. Devuelven un ROWSET. O sea que la salida de una de estas funciones es una simple declaración SELECT.  
    Una de las limitaciones de las vistas, es que no podemos incluir parámetros en la vista que estamos creando. Usualmente lo resolveríamos con un filtro WHERE cuando invocamos a la Vista.
    Sin embargo, esto puede requerir la construcción de una cadena de caracteres que constituye la consulta SELECT a ejecutar, aumentando la complejidad de la solución. Puede conseguir la funcionalidad de una Vista parametrizada, usando una Función Tabular.

    Características:

    El siguiente ejemplo crea una Función Tabular En Línea, que devuelve los nombres de los empleados para un Administrador en particular.

      CREATE FUNCTION HumanResources.EmployeesForManager 
      (@ManagerId int)  
      RETURNS TABLE 
      AS 
      RETURN  
      ( 
      SELECT FirstName, LastName 
      FROM HumanResources.Employee Employee  
      INNER JOIN Person.Contact Contact  
      ON Employee.ContactID = Contact.ContactID 
      WHERE ManagerID = @ManagerId  
      )
    

    Use una Función Tabular En Línea donde normalmente usaría una Vista, tal como en la cáusula FROM de una sentencia SELECT.
    El siguiente ejemplo devuelve todos los nombres de los empleados para dos administradores (3 y 6) :
    SELECT * FROM HumanResources.EmployeesForManager(3)
    SELECT * FROM HumanResources.EmployeesForManager(6)

    Caracteristicas:

    La salida se puede utilizar dentro de joins o querys como si fuera una tabla de estándar.
    El tipo de datos que devuelve es TABLE.
    La cláusula RETURNS especifica un TABLE sin información adicional, esta debe ser una simple sentencia SELECT

    Funciones Tabulares Multi-Sentencia

    Caracteristicas:

    El siguiente ejemplo crea una Función Tabular Multi-Sentencia llamada @tbl_Employees con dos columnas.
    La segunda columna cambia dependiendo del valor del parámetro de entrada @ format.

      CREATE FUNCTION HumanResources.EmployeeNames(@format nvarchar(9)) 
      RETURNS @tbl_Employees TABLE 
      ( 
      EmployeeID int PRIMARY KEY,  
      EmployeeName nvarchar(100) 
      ) 
      AS 
      BEGIN 
        IF (@format = 'SHORTNAME') 
          INSERT @tbl_Employees  
          SELECT [BusinessEntityID], LastName  
          FROM HumanResources.vEmployee 
        ELSE IF (@format = 'LONGNAME') 
          INSERT @tbl_Employees  
          SELECT [BusinessEntityID], (FirstName + ' ' + LastName)  
          FROM HumanResources.vEmployee 
      RETURN 
      END 
    
    

    Los siguientes ejemplos obtienen la lista de empleados en su forma corta y larga, respectivamente:

      SELECT * 
      FROM HumanResources.EmployeeNames('SHORTNAME’) 
    
      SELECT *
      FROM HumanResources.EmployeeNames('LONGNAME’) 
    

    Características:

    Tipos de Inicio de Sesión en SQL Server

    Seguridad General en SQL Server

    Seguridad Amenazas de SQL

    Seguridad: Entidades y objetos de Base de Datos

    Seguridad: Elementos protegibles

    Ámbito protegible: Los elementos protegibles son los recursos cuyo acceso es regulado por el sistema de autorización del motor de base de datos SQL Server. Por ejemplo, una tabla en un elemento protegible. Algunos elementos protegibles pueden estar incluidos en otros, con lo que se crean jerarquías anidadas denominadas ámbitos que a su vez se pueden proteger. Los ámbitos protegibles son servidor, base de datos y esquema.

    Seguridad: Jerarquía de Permisos en Base de Datos

    Conceptos sobre cifrado en SQL Server

    Triggers

    Un "trigger" (disparador o desencadenador) es un tipo de stored procedure que se ejecuta cuando se intenta modificar (ABM O CRUD) los datos de una tabla o vista.

    Caracteristicas

    Uso de los triggers

    Consideraciones acerca del uso de triggers

    Sintaxis de triggers
      CREATE TRIGGER nombre_trigger 
      ON { tabla|vista }
      [ WITH ENCRYPTION ] 
      { AFTER | INSTEAD OF }
      { INSERT, UPDATE, DELETE }
      [ NOT FOR REPLICATION ]
      AS 
      Bloque de instrucciones
    

    WITH ENCRYPTION: Encripta el código del Trigger para que no pueda ser interpretado por nadie mas.

    AFTER: Indica que el Trigger se ejecutará después de que las operaciones DML se hayan ejecutado correctamente. Esta clausula no se aplica en las vistas.

    INSTEAD OF: Permite ejecutar el Trigger en lugar de la operación DML, es decir, SQL Server ignora dicha operación para ejecutar al Trigger.
    Tener en cuenta que solo debe existir un Trigger tipo INSTEAD OF para cada operación DML.

    INSERT, UPDATE, DELETE:

    NOT FOR REPLICATION: Evita que el Trigger se ejecute cuando una operación de replicación vaya a alterar nuestra tabla asociada.

    Se aplica cuando estás replicando un servidor SQL Server a otro servidor. En ese caso, si el trigger llega a correr durante el proceso de replicación, eso a menudo no es el comportamiento deseado y puede corromper los datos en el servidor replicado.
    Por esta razón, se puede agregar NOT FOR REPLICATION a la definición de un trigger para que este no se ejecute si la modificación de datos ocurre durante el proceso de replicación.

    Triggers DML:

    Creación de triggers

      CREATE TRIGGER Empl_Borrar 
      ON Employees
      FOR DELETE 
      AS
      IF (SELECT COUNT(*) FROM Deleted) > 1
      BEGIN
        ROLLBACK TRANSACTION   
        THROW 50000, 'NO SE PUEDE BORRAR MAS DE UN EMPLEADO A LA VEZ',1
      END
    

    Modificacion de triggers

      ALTER TRIGGER Empl_Borrar 
      ON Employees
      FOR DELETE 
      AS
      IF (SELECT COUNT(*) FROM Deleted) > 6
      BEGIN
        THROW 50000,' NO SE PUEDE BORRAR MAS DE 6 EMPLEADOS X VEZ ',  1
        ROLLBACK TRANSACTION
      END
    

    Funcionamiento de un TRIGGER INSERT

      CREATE TRIGGER OrdDet_Insert
      ON [Order Details]
      FOR INSERT
      AS
      UPDATE P SET 
      UnitsInStock = (P.UnitsInStock – I.Quantity)
      FROM Products AS P INNER JOIN Inserted AS I
      ON P.ProductID = I.ProductID
    

    Funcionamiento de un trigger UPDATE

      AS
      IF UPDATE (EmployeeID)
      BEGIN TRANSACTION
    	  RAISERROR (' No se puede procesar la transacción
    	  ***** El ID de Empleado NO puede ser modificado!!', 10, 1)
    	  ROLLBACK TRANSACTION
    

    Funcionamiento de un Trigger INSTEAD OF

    1)Creamos el trigger (INSERT)
      CREATE TRIGGER dbo.tr_Categoria 
      ON dbo.categories
      AFTER INSERT 
      AS
      PRINT ‘Se agregaron la siguiente cantidad de filas’;
    
    2)Damos un alta de categoria:
      INSERT INTO Categories (CategoryName,Description)
      VALUES ('Bebidas Frias','BIEN HELADAS') 
    
    3)Modificamos el trigger anterior
      Alter TRIGGER dbo.tr_Categoria 
      ON dbo.categories
      INSTEAD OF INSERT
      AS
      PRINT "Se agregaron la siguiente cantidad de filas";
    
    4)Nueva alta de categoria:
      INSERT INTO Categories (CategoryName,Description)
      VALUES (Infusiones',’Bebidas derivadas de las hojas y flores')
      Ejecutamos
      Comprobamos con el resultado anterior
    

    Triggers INSTEAD OF

    Creo una tabla con los clientes de Brazil y Argentina.
      SELECT *
      INTO ClientesBra
      FROM Customers
      WHERE country=‘Brazil'
      SELECT * FROM ClientesBra
    
      SELECT *
      INTO ClientesArg
      FROM Customers
      WHERE country= 'Argentina'
      SELECT * FROM ClientesArg
    
      CREATE VIEW ArgBra AS
      SELECT * 
      FROM ClientesArg
      UNION
      SELECT * 
      FROM ClientesBra  
    

    Funcionamiento de un desencadenador INSTEAD OF

    Actualizo un telefono de un cliente de brasil desde la vista:

    Codigo:
    Update ArgBra set Phone=‘12345’ where Customerid=‘CACTU’
    ¿ como se que tabla debo actualizar ? Para eso creo el trigger , reemplazando el codigo que actualiza sobre la vista por el que actualiza la tabla ClientesArg o ClientesBra segun corresponda.

      CREATE trigger t_clientes
      ON ArgBra INSTEAD OF update
      AS
      BEGIN
      DECLARE @pais nvarchar(15)
      DECLARE @telefono nvarchar(20)
      DECLARE @idCliente nvarchar(5)
      SET @pais =(select country from inserted)
      SET @telefono=(select phone from inserted)
      SET @idCliente=(select Customerid from inserted)
      IF @pais='Argentina'
          BEGIN
    	      UPDATE ClientesArg SET phone=@telefono
            WHERE CustomerID=@idCliente
          END
      ELSE
          BEGIN
            UPDATE ClientesBra SET phone=@telefono
            WHERE CustomerID=@idCliente
          END
      END
    

    DESHABILITAR UN TRIGGER

      ALTER TABLE employees
      DISABLE TRIGGER empleado_trigge
    

    Consideraciones acerca del rendimiento

    Triggers DDL:

    Triggers DML => INSTEAD OF

      CREATE TRIGGER TR_BorradoSelectivo on Clientes INSTEAD OF DELETE
      AS
      BEGIN
       DELETE c
       FROM Clientes C
       INNER JOIN DELETED d
          ON C.idCliente=D.idCliente
       WHERE C.CreditoTotal=0
      END 
    

    Triggers DML => AFTER

      CREATE TRIGGER TR_CompruebaCreditoTotal ON Clientes AFTER UPDATE
      AS
      BEGIN
      IF UPDATE(CreditoTotal)
       -- Se está actualizando el campo crédito total, comprobemos
       -- las restricciones.
       BEGIN
         IF EXISTS( SELECT IdCliente
         FROM RECIBOS
         WHERE Estado=’PEN’ AND idCliente IN (SELECT idCliente FROM DELETED)
         )
         BEGIN
          ROLLBACK -- Deshacemos la transacción impidiendo que se actualize
          RAISERROR (‘No se pueden actualizar el crédito de clientes con recibos pendientes’,16,1)
         END
       END
      END 
    

    Triggers DDL: a nivel de base de datos

        CREATE / ALTER /DROP View 
        CREATE / ALTER /DROP Table 
        CREATE / ALTER /DROP Schema
      
        CREATE TRIGGER TablasDocumentadas
        ON DATABASE
        FOR CREATE_TABLE
        AS
        BEGIN
          DECLARE @TabName Sysname 
          SELECT @TabName=EventData().value(‘(/EVENT_INSTANCE/ObjectName)[1]’,’sysname’)
          IF NOT EXISTS(SELECT * FROM TablasDocumentadas WHERE TableName=@TabName)
          BEGIN
            ROLLBACK -- Deshacemos la transacción impidiendo que se actualize
            RAISERROR (‘No se pueden crear tablas indocumentadas en nuestro sistema’,16,1)
          END
        END 
      

    Triggers DDL: a nivel Servidor

      CREATE LOGIN
      CREATE/ALTER/DROP 
    
      CREATE TRIGGER LoginsConTresLetrasYGuionBajo
      ON ALL SERVER
      FOR DDL_LOGIN_EVENTS
      AS
      BEGIN
        DECLARE @ObjName Sysname
        SELECT @ObjName=EventData().value(‘(/EVENT_INSTANCE/ObjectName)[1]’,’sysname’)
        IF NOT @ObjName LIKE ‘[A-Z][A-Z][A-Z][_]%’
        BEGIN
          ROLLBACK
          RAISERROR (‘Todos los logins deben comenzar por tres letras y un guión bajo’,16,1)
        END
      END 
    

    Niveles de aislamiento

    Las cuatro propiedades ACID son Atomicidad, Consistencia, Aislamiento y Durabilidad. Estas cuatro propiedades definen las transacciones de la base de datos. Cuando se cumplen, garantizan su validez, incluso en caso de fallo, corte de energía u otros errores.

    Niveles

    READ UNCOMMITED: Lecturas no confirmadas, realmente lo que sucede en este nivel de aislamiento es que los usuarios pueden leer datos que aún no están confirmados.

    Presenta los siguientes problemas:

    READ COMMITED: No lee datos que no estén confirmados. Las lecturas solo se ven bloqueadas por las escrituras

    Presenta los siguientes problemas:

    REPETEABLE READ: Garantiza que dos select consecutivas dentro de una transacción devolverán la misma información.

    Presenta los siguientes problemas:

    SERIALIZABLE: Las lecturas solo se ven bloqueadas por las escrituras. Este es el nivel máximo de aislamiento y también genera el nivel máximo de bloqueos.

    Niveles – Comparacion Lectura Sucia (Dirty Read) Lectura No Repetible (Non-Repetable Read) Lectura Fantasma (Phantom Read) Descripción
    READ Permitida ✔️ Permitida ✔️ Permitida ✔️ La transacción puede ver cambios no confirmados de otras transacciones. Mayor concurrencia, menor integridad.
    UNCOMMITTED Permítida ✔️ Permítida ✔️ Permítida ✔️
    READ COMMITTED No permitida ❌ Permitida ✔️ Permitida ✔️ Solo se leen datos confirmados. Pero los datos pueden cambiar entre lecturas dentro de una misma transacción.
    REPEATABLE READ No permitida ❌ No permitida ❌ Permitida ✔️ Los datos leídos no cambian durante la transacción, pero aún pueden aparecer nuevas filas que cumplan una condición.
    SERIALIZABLE No permitida ❌ No permitida ❌ No permitida ❌ El más estricto. Se comporta como si las transacciones se ejecutaran secuencialmente. Máxima integridad, menor concurrencia.

    Nuevo nivel de aislamiento de instantánea

    SNAPSHOT Isolation Level:Esta estrategia permite evitar todos los problemas descritos, sin necesidad de bloquear las filas, de tal forma que una sentencia SELECT devolverá exactamente los mismos datos cada vez que se ejecute.

    Cursores

    Caracteristicas

    Intrucciones

    DECLARE CURSOR: Define los atributos de un cursor de servidor de Transact-SQL,como su comportamiento de desplazamiento y la consulta utilizada para generar el conjunto de resultados sobre el que opera el cursor.

    Sentencia OPEN: Abre un cursor del servidor Transact-SQL y lo llena ejecutando la instrucción Transact-SQL especificada en la instrucción DECLARE CURSOR o SET cursor_variable.

    Sentencia FETCH: Recupera una fila específica de un cursor de servidor de Transact-SQL. Esta sentencia se utiliza para leer los registros del cursor: Su sintaxis es la siguiente:

      FETCH 
          [[NEXT | PRIOR | FIRST | LAST 
              | ABSOLUTE { n | @nvar } 
              | RELATIVE { n | @nvar } 
            ] 
            FROM 
          ] 
      { { [ GLOBAL ] cursor_name } | @cursor_variable_name } 
      [ INTO @variable_name [ ,...n ] ] 
     

    Sus argumentos son:

    NEXT: Devuelve la fila de resultados inmediatamente después de la fila actual y se posiciona en la fila devuelta.

    PRIOR: Devuelve la fila de resultados inmediatamente anterior de la fila actual y se posiciona en la fila devuelta.

    FIRST: Devuelve la primera fila en el cursor y la convierte en la fila actual.

    LAST: Devuelve la última fila en el cursor y la convierte en la fila actual.

    Intrucciones

    ABSOLUTE { n | @nvar}

    Si n o @nvar es positivo, devuelve la fila n de del cursor y hace la fila devuelta la fila actual (o sea, se posiciona en la fila n). Si n o @ nvar es negativo, devuelve la fila n antes de que finalice el cursor y hace que la fila devuelta sea la fila actual. Si n o @ nvar es 0, no se devuelven filas. n debe ser una constante entera y @ nvar debe smallint, tinyint o int.

    RELATIVE { n | @nvar}

    Trabaja similar a ABSOLUTE pero devuelve la fila n desde la fila actual donde esta posicionado el cursor.

    Sentencia CLOSE: Cierra un cursor abierto mediante la liberación del conjunto actual de resultados y todos los bloqueos de cursor mantenidos en las filas en las que está colocado.
    CLOSE deja las estructuras de datos accesibles para que se puedan volver a abrir, pero las recuperaciones y las actualizaciones posicionadas no se permiten hasta que se vuelva a abrir el cursor.
    CLOSE debe ejecutarse en un cursor abierto, por lo que no se permite en cursores que sólo están declarados o que ya están cerrados.

    Sentencia DEALLOCATE: Quita una referencia a un cursor. Cuando se ha quitado la última referencia al cursor, Microsoft SQL Server libera las estructuras de datos que componen el cursor.

    Ejemplo:

    A continuación, juntaremos todos los pasos descriptos previamente y crearemos el ejemplo más simple de un cursor el cual recorrerá la tabla Production.ProductDescription de la base de datos AdventureWorks y mostrará por pantalla el valor del registro Description luego que el mismo ha sido copiado a la variable @Description.

      DECLARE @Description AS nvarchar(400) 
      DECLARE ProdInfo CURSOR FOR SELECT [Description] FROM Production.ProductDescription 
      OPEN ProdInfo
    	  FETCH NEXT FROM ProdInfo INTO @Description
    	  WHILE @@fetch_status = 0
    	  BEGIN
    		    PRINT @Description
    	        FETCH NEXT FROM ProdInfo INTO @Description
    	  END
      CLOSE ProdInfo
      DEALLOCATE ProdInfo
    
    SQL Consultas Dinámicas

    SQL – Consultas Dinámicas

    Son consultas que no están determinadas en tiempo de compilación. Se compilan en tiempo de ejecución.

    Y su ejecución se determina la primera vez que se ejecuta, en las siguientes se usa el mismo.

    EXEC SP_EXECUTESQL
    Consulta Sin parámetros - Cadena Unicode (nvarchar)
    Con usuario determinado opcional
    Consulta Con parámetros - Cadena Unicode (nvarchar) para tipo de datos en parámetros - Y valores de los mismos
    Para ejecutar una cadena SQL
    { EXEC | EXECUTE } { ( @string_variable | [ N ]'tsql_string' ) [ + ...n ] } [ AS { LOGIN | USER } ] = 'name' ] [;]
    Declare @tabla Nvarchar(30)
    Declare @query Nvarchar(100)

    Set @tabla = 'Person.Address'
    Set @query = N'Select * from ' + @tabla
    Exec (@query)
    Para ejecutar una cadena SQL con parámetros
    sp_executesql [ @stmt = ] statement [ { , [ @params = ] N'@parameter_name data_type [ OUT | OUTPUT ] [,...n]' } { , [ @param1 = ] 'value1' [ ,...n ] } ]
    El orden de los parámetros debe ser idéntico al de los valores, sino da error.
    Declare @tabla Nvarchar(30)
    Declare @query Nvarchar(500)
    Declare @params Nvarchar(200)
    Declare @edad1 int
    Declare @edad2 int

    Set @tabla = 'Empleados'
    Set @edad1=30
    Set @edad2=75
    Set @params= N'@edad1 int, @edad2 int'
    Set @query = 'Select * from ' + @tabla + ' Where Edad BETWEEN @edad1 and @edad2'
    Exec sp_executesql @query, @params, @edad1, @edad2

    Transacciones y bloqueos

    Variables Tabla en SQL Server

    Inconvenientes

    No podemos cambiar la definición de la tabla una vez declarada.
    No podemos utilizar índices que no sean agrupados.
    No se pueden utilizar en INSERT INTO ni en SELECT INTO.
    No podemos utilizar funciones en las restricciones.

    Ejemplo:
      DECLARE @VariableTabla TABLE (Campo1 int, Campo2 char(50))
      INSERT INTO @VariableTabla VALUES (1,'Primer campo')
      INSERT INTO @VariableTabla VALUES (2,'Segundo campo')
      SELECT * FROM @VariableTabla  
    

    Manejo de Errores con SQL

      TRY - CATCH 
      BEGIN TRY
        { sql_statement | statement_block }
      END TRY
      BEGIN CATCH
        { sql_statement | statement_block }
      END CATCH
    
    Ejemplo:
      BEGIN TRY
        SELECT *
          FROM sys.messages
          WHERE message_id = 21;
      END TRY
      GO   --Error!!!!!!
      BEGIN CATCH
        SELECT ERROR_NUMBER () AS ErrorNumber;
      END CATCH;
      GO
    
    Sentencia THROW Ejemplo:
      THROW 51000,'The record does not exist.', 1;
    
    Resultado:

    Msg 51000, Level 16, State 1, Line 1 The record does not exist.
    Sentencia RAISERROR (deprecado)
    Sentencia PRINT

    Transacciones Explisitas

      BEGIN TRANSACTION, 
      COMMIT TRANSACTION, 
      ROLLBACK TRANSACTION
    

    Transacciones Implícitas

      SET IMPLICIT_TRANSACTIONS ON  
    

    La variable @@ERROR devuelve el código de error producido

      USE PUBS
    BEGIN TRAN
    UPDATE authors 
    SET state = 'FL'
    WHERE state = 'KS'
    IF @@ERROR <> 0 BEGIN
        ROLLBACK TRAN
        GOTO ON_ERROR
     END
    
    UPDATE jobs 
    SET min_lvl = min_lvl - 10
    IF @@ERROR <> 0 BEGIN
        ROLLBACK TRAN
        GOTO ON_ERROR
     END
    COMMIT TRAN
    ON_ERROR:
    SELECT * FROM authors
    WHERE state = 'FL'
    

    BATCHS y SCRIPTS

    BATCHS

    Un Batch es un lote de una o más sentencias Transact-SQL, enviadas en una sola vez desde una aplicación a Microsoft SQL Server para ser ejecutada en un solo intento. La cláusula GO indica el fin de un Batch.

    Lo utilitarios de SQL Server interpretan el GO como un signo de que el Batch (conjunto de sentencias) debe ser enviado para su ejecución. El Batch actual, está compuesto por todas las sentencias antes de la cláusula GO.

    Una sentencia Transact-SQL no puede ocupar en una misma línea el comando GO

    Las variables locales definidas por el usuario son limitadas dentro del Batch, esto significa que no pueden ser referenciadas después del comando GO.

    SCRIPTS

    Es un programa, o sea un conjunto de comandos, que se le da al motor SQL para decirle lo que debe hacer y en qué orden debe hacerlo. Los Scripts son series de Batchs ejecutados uno después de otro.

    Comando GO

    Indica a SQL Server el final de un lote de instrucciones Transact-SQL. GO no es una instrucción Transact-SQL, sino un comando

    El SQL Server interpreta el GO como una señal de que deben enviar el lote actual de instrucciones Transact-SQL a una instancia de SQL Server. El lote actual de instrucciones está formado por todas las instrucciones especificadas desde el último comando GO o desde el comienzo de la sesión.

    Control de Flujo

    Bloque BEGIN – END: Encierra un conjunto de instrucciones Transact-SQL de forma que se pueda ejecutar un grupo de instrucciones Transact-SQL. BEGIN y END son palabras clave del lenguaje de control de flujo.

    Se utilizan para controles de flujos como IF, ELSE, WHILE.

    Bloque IF … ELSE: Impone condiciones en la ejecución de una instrucción Transact-SQL.
    La instrucción Transact-SQL (sql_statement) que sigue a Boolean_expression se ejecuta si Boolean_expression se evalúa como TRUE.
    La palabra clave opcional ELSE es una instrucción Transact-SQL alternativa que se ejecuta cuando Boolean_expression se evalúa como FALSE o NULL.

    Construcción WHILE, BREAK y CONTINUE

    Establece una condición para la ejecución repetida de una instrucción o bloque de instrucciones SQL. Las instrucciones se ejecutan repetidamente siempre que la condición especificada sea verdadera. Se puede controlar la ejecución de instrucciones en el bucle WHILE con las palabras clave BREAK y CONTINUE.

    BREAK:Produce la salida del bucle WHILE más interno. Se ejecutan las instrucciones que aparecen después de la palabra clave END, que marca el final del bucle.

    CONTINUE:Hace que se reinicie el bucle WHILE y omite las instrucciones que haya después de la palabra clave CONTINUE.

    GOTO

    La instrucción GOTO provoca que, en la ejecución de un lote de Transact-SQL, se salte a una etiqueta. Ninguna de las instrucciones situadas entre la instrucción GOTO y la etiqueta se ejecutarán. El nombre de la etiqueta se define con la sintaxis:

    GOTO label_name

    La etiqueta que constituye el objetivo de un GOTO sólo identifica el destino del salto.

    WAITFOR

    La instrucción WAITFOR suspende la ejecución de un lote, un procedimiento almacenado o una transacción hasta que:
    Haya pasado un intervalo de tiempo especificado.
    Se haya alcanzado una hora del día especificada.
    Una instrucción RECEIVE especificada modifique o devuelva como mínimo una fila en una cola de Service Broker.
    WAITFOR DELAY '00:00:02' print 'pasaron 2 segundos'

    Sentencia EXECUTE

    Ejecuta uno de los siguientes módulos: procedimiento almacenado del sistema, procedimiento almacenado definido por el usuario, función con valores escalares definida por el usuario o procedimiento almacenado extendido.
    Ejecuta una cadena de comandos o una cadena de caracteres dentro de un proceso por lotes de Transact-SQL.

    EXECUTE ('select * from titles')

    Expresión CASE

    Descripción: Evalúa una lista de condiciones y devuelve una de las varias expresiones de resultado posibles. La función "case" compara 2 o más valores y devuelve un resultado.

    Función: Simple CASE:

    La función CASE sencilla compara una expresión con un conjunto de expresiones sencillas para determinar el resultado.

    La sintaxis es la siguiente:

      case VALORACOMPARAR
       when VALOR1 then RESULTADO1
       when VALOR2 then RESULTADO2
       ...
       else RESULTADO3
      end
    

    Por cada valor hay un "when" y un "then"; si encuentra un valor coincidente en algún "where" ejecuta el "then" correspondiente a ese "where", si no encuentra ninguna coincidencia, se ejecuta el "else"; si no hay parte "else" retorna "null". Finalmente se coloca "end" para indicar que el "case" ha finalizado.
    Ejemplo: Un profesor guarda las notas de sus alumnos de un curso en una tabla llamada "alumnos" que consta de los siguientes campos:

    - nombre (30 caracteres),
    - nota (valor entero entre 0 y 10, puede ser nulo).
    Mostrar los nombres, notas de los alumnos y en una columna extra llamada "resultado" empleamos un case que testee la nota y muestre un mensaje diferente si en dicho campo hay un valor:
    - 0, 1, 2 ó 3: 'libre';
    - 4, 5 ó 6: 'regular';
    - 7, 8, 9 ó 10: 'promocionado';
    select nombre,nota,
    case nota
     when 0 then 'libre'
     when 1 then 'libre'
     when 2 then 'libre'
     when 3 then 'libre'
     when 4 then 'regular'
     when 5 then 'regular'
     when 6 then 'regular'
     when 7 then 'promocionado'
     when 8 then 'promocionado'
     when 9 then 'promocionado'
     when 10 then 'promocionado'
    end
    from alumnos
    

    Note que cada "where" compara un valor puntual, por ello los valores devueltos son iguales para algunos casos. Note que como omitimos la parte "else", en caso de que el valor no encuentra coincidencia con ninguno valor "when", retorna "null".

    Función: Searched CASE:

    La función CASE buscada evalúa un conjunto de expresiones booleanas para determinar el resultado. Podemos realizar comparaciones en cada "where". La sintaxis es la siguiente:

    case
     when VALORACOMPARAR OPERADOR VALOR1 then RESULTADO1
     when VALORACOMPARAR OPERADOR VALOR2 then RESULTADO2
     ...
     else RESULTADO3
    end
    

    Mostramos los nombres de los alumnos y en una columna extra llamada "resultado" empleamos un case que teste si la nota es menor a 4, está entre 4 y 7 o supera el 7:

    select nombre, nota, resultado=
      case 
      when nota<4 then 'libre'
      when nota >=4 and nota<7 then 'regular'
      when nota>=7 then 'promocionado'
      else 'sin nota'
     end
    from alumnos;
    

    Ordenamiento con CASE

    Se puede utilizar la función CASE realizar ordenamientos que no sean alfabéticos o numéricos, tanto ascendentes como descendentes. Por ejemplo, queremos realizar un reporte de todos los autores ordenado por el estado en el que viven pero con el siguiente criterio: Primero los que vivan en California, luego los que viven en Washington y el resto ordenado alfabéticamente.

    select state, au_fname, au_lname
    from authors
    order by  case when state = “CA” then 1
              when state = “WA” then 2
    else 3 end,
    state  
    

    Manejo de Errores con SQL

    TRY - CATCH

    Description: Además del @@ERROR existe una sentencia más práctica a la hora de detectar que se ha producido un error en un procedimiento y ejecutar un ROLLBACK en consecuencia. Al igual que en otros lenguajes como C#.NET se puede abrir un TRY para la secuencia de comandos que podrían dar error y un CATCH para realizar un “deshacer” si esto ocurre.

    Características: La a partir de la versión 2005 implementa un mecanismo de control de errores para T-SQL.
    e puede incluir un grupo de instrucciones T-SQL en un bloque TRY. Si se produce un error en el bloque TRY, el control se transfiere a otro grupo de instrucciones que está incluido en un bloque CATCH.
    Un bloque TRY debe ir seguido inmediatamente por un bloque CATCH. Un bloque CATCH se inicia con la instrucción BEGIN CATCH y finaliza con la instrucción END CATCH. En Transact-SQL, cada bloque TRY se asocia a un sólo bloque CATCH.

    Sintaxis:

      BEGIN TRY
        { sql_statement | statement_block }
        END TRY
        BEGIN CATCH
          { sql_statement | statement_block }
          END CATCH
    

    Cuando utilice la construcción TRY…CATCH, tenga en cuenta las siguientes directrices y sugerencias:
    Un bloque TRY debe ir seguido inmediatamente por un bloque CATCH asociado. Si se incluye cualquier otra instrucción entre las instrucciones END TRY y BEGIN CATCH se genera un error de sintaxis.
    Cada construcción TRY…CATCH debe encontrarse en un solo lote, procedimiento almacenado o desencadenador.
    Por ejemplo, no se puede colocar un bloque TRY en un lote y el bloque asociado CATCH en otro. La siguiente secuencia de comandos generaría un error:

      BEGIN TRY
        SELECT *
        FROM sys.messages
        WHERE message_id = 21;
      END TRY
      GO   --Error!!!!!!
      BEGIN CATCH
        SELECT ERROR_NUMBER () AS ErrorNumber;
      END CATCH;
      GO
    

    Un bloque CATCH debe seguir inmediatamente a un bloque TRY.

    Las construcciones TRY…CATCH pueden estar anidadas. Esto significa que las construcciones TRY…CATCH se pueden colocar dentro de otros bloques TRY y CATCH. Cuando se produce un error dentro de un bloque TRY anidado, el control del programa se transfiere al bloque CATCH que está asociado al bloque TRY anidado.

    Sentencia THROW: Produce una excepción y transfiere la ejecución a un bloque CATCH de una construcción TRY...CATCH.

    Ejemplo:
    THROW 51000,'The record does not exist.', 1;
    Resultado:

    Msg 51000, Level 16, State 1, Line 1 The record does not exist.

    Lo nuevo en TRY - CATCH es el THROW en la que ahora podemos manejar los errores internos de SQL Server. Cuando poseemos una estructura TRY CATCH, al fallar la sentencia TRY se maneja un error interno de SQL Server, THROW permite capturar el error interno que se ejecuta en el TRY y nos permite mostrarlo como mensaje dentro del bloque CATCH, lo que nos va permitir administrar y poder almacenar los errores internos que se originan en nuestras transacciones programadas, podemos manejar nuestro propio log de errores y de esa manera generar estadísticas por errores, a fin de mejorar nuestra programación y como tal también nuestras aplicaciones.

    TRY CATCH THROW: La captura de errores ha cambiado T-SQL.
    Cuando SQL Server 2005 introdujo la sintaxis BEGIN TRY y BEGIN CATCH, que era una gran mejora con respecto al manejo de errores anterior sobre la base de comprobación @@ERROR después de cada declaración. T-SQL, se unió a la fila de los lenguajes de programación, no más que un lenguaje de acceso a datos. La experiencia ha demostrado que el control de excepciones conduce a un mejor código en comparación con los controles de error.
    Pero cuando se trata de utilizar el nuevo TRY / CATCH de manejo de excepciones en el código T-SQL, se hizo evidente rápidamente uno de los problemas: el bloque CATCH se enmascara los metadatos de error original: número de error / gravedad / estado, el texto de error, la línea de origen y así sucesivamente. Dentro de un bloque CATCH el código sólo se le permitió subir un nuevo archivo * error *. Claro, la información del error original podría ser transmitida en el mensaje de error generado, pero sólo como un mensaje. El código de todos los errores importantes se ha cambiado. Esto puede parecer un tema menor, pero resulta que tiene un efecto cascada muy en serio: la persona que llama ahora tiene que entender los nuevos códigos de error, en lugar de los códigos de error del sistema original.
    Si el código de la aplicación se preparó para controlar interbloqueos (código de error 1205) de una manera determinada (por ejemplo, vuelva a intentar la operación), con un try de T-SQL / catch el código de error estancamiento que de repente se traduce en algo por encima de 50000.

    Sentencia RAISERROR (deprecado): Con la introducción de THROW, RAISERROR fue declarado obsoleto. Hasta el momento coexisten ambos.

    Sentencia PRINT: Devuelve al cliente un mensaje definido por el usuario. Devuelve una cadena de caracteres o una constante de cadena Unicode

    Transacciones

    Administración de Transacciones

    Las aplicaciones controlan las transacciones principalmente al especificar cuándo se inicia y finaliza una transacción.
    El sistema también debe ser capaz de controlar correctamente los errores que terminan una transacción antes de que se concluya.
    De manera predeterminada, las transacciones se administran en las conexiones. Cuando se inicia una transacción en una conexión, todas las instrucciones Transact-SQL ejecutadas en esa conexión forman parte de la transacción hasta que ésta finaliza. No obstante, en una sesión de conjunto de resultados activos múltiples (MARS), una transacción de Transact-SQL explícita o implícita se convierte en una transacción de lote que se administra en los lotes. Cuando se termina el lote, si la transacción de lote no se confirma ni se revierte, SQL Server la revierte automáticamente.
    Existen dos tipos de transacciones. Transacciones Implícitas y Transacciones Explícitas.

    Transacciones Explícitas: Una transacción explícita es aquella en que se define explícitamente el inicio y el final de la transacción. Las transacciones explícitas también recibían el nombre de transacciones definidas por el usuario.
    Las secuencias de comandos Transact-SQL utilizan las instrucciones BEGIN TRANSACTION, COMMIT TRANSACTION, ROLLBACK TRANSACTION de Transact-SQL para definir transacciones explícitas.
    BEGIN TRANSACTION: Marca el punto de inicio de una transacción explícita para una conexión.

    COMMIT TRANSACTION: Se utiliza para finalizar una transacción correctamente si no hubo errores. Todas las modificaciones de datos realizadas en la transacción se convierten en parte permanente de la base de datos. Se liberan los recursos ocupados por la transacción.

    ROLLBACK TRANSACTION: Se utiliza para eliminar una transacción en la que se encontraron errores. Todos los datos modificados por la transacción vuelven al estado en el que estaban al inicio de la transacción. Se liberan los recursos ocupados por la transacción.

    Transacciones Implícitas: Cuando una conexión funciona en modo de transacciones implícitas, SQL Server Database Engine (Motor de base de datos de SQL Server) inicia automáticamente una nueva transacción después de confirmar o revertir la transacción actual.
    No tiene que realizar ninguna acción para delinear el inicio de una transacción, sólo tiene que confirmar o revertir cada transacción. El modo de transacciones implícitas genera una cadena continua de transacciones.
    SET IMPLICIT_TRANSACTIONS ON

    Chequeo de Errores dentro de la Transacción: La variable @@ERROR devuelve el código de error producido

      USE PUBS
      BEGIN TRAN
      UPDATE authors 
      SET state = 'FL'
      WHERE state = 'KS'
      IF @@ERROR <> 0 BEGIN
        ROLLBACK TRAN
        GOTO ON_ERROR
      END
      UPDATE jobs 
      SET min_lvl = min_lvl - 10
      IF @@ERROR <> 0 BEGIN
        ROLLBACK TRAN
        GOTO ON_ERROR
      END
      COMMIT TRAN
      ON_ERROR:
      SELECT * FROM authors
      WHERE state = 'FL'
    

    Transacciones(Nivel de Aislamiento): El nivel de aislamiento con el que se ejecuta una instrucción Transact-SQL determina su comportamiento de bloqueo y de versión de fila.
    El nivel de aislamiento con el que se ejecuta una instrucción Transact-SQL determina su comportamiento de bloqueo y de versión de fila.

    READ UNCOMMITTED: es el nivel de aislamiento menos restrictivo porque omite los bloqueos realizados por otras transacciones. Las transacciones que se ejecutan con READ UNCOMMITTED pueden leer valores de datos modificados que aún no han confirmado otras transacciones; éstos se conocen como lecturas no confirmadas.

    READ COMMITTED: Es el nivel de aislamiento predeterminado en SQL Server. Impide las lecturas no confirmadas al especificar que las instrucciones no pueden leer valores de datos modificados que aún no hayan confirmado otras transacciones.

    REPEATABLE READ: Es un nivel de aislamiento más restrictivo que READ COMMITTED. Incluye READ COMMITTED y además especifica que ninguna otra transacción puede modificar ni eliminar datos que la transacción actual haya leído hasta que ésta no se confirme. La simultaneidad es menor que en READ COMMITTED porque durante la transacción se mantienen bloqueos compartidos en los datos leídos en lugar de liberarlos al final de cada instrucción.

    SNAPSHOT: La transacción únicamente puede reconocer las modificaciones de datos confirmadas antes del comienzo de la misma. Las instrucciones que se ejecuten en la transacción actual no verán las modificaciones de datos efectuadas por otras transacciones después del inicio de la transacción actual. El efecto es el mismo que se obtendría si las instrucciones de una transacción obtuviesen una instantánea de los datos confirmados tal como se encontraban al comienzo de la transacción.

    SERIALIZABLE: Es el nivel de aislamiento más restrictivo, dado que bloquea intervalos enteros de claves y mantiene los bloqueos hasta que la transacción finaliza. Incluye REPEATABLE READ y agrega la restricción de que otras transacciones no pueden insertar filas nuevas en intervalos que haya leído la transacción hasta que ésta no finalice.

    Sentencias de Transacción(ROLLBACK y SAVE):Se puede evitar tener que deshacer toda la transacción empleando un punto de almacenamiento para deshacer hasta cierto punto de la transacción, en lugar de llegar hasta el comienzo de la transacción.
    Todas las modificaciones producidas hasta el punto de almacenamiento siguen siendo válidas y no se deshacen, pero las instrucciones ejecutadas después del punto de almacenamiento (que debe especificarse en la transacción) y hasta la instrucción ROLLBACK se deshacen.
    Las instrucciones situadas a continuación de la instrucción ROLLBACK seguirán ejecutándose. Si se deshace posteriormente la transacción sin especificar un punto de almacenamiento, todas las modificaciones se anulan hasta el principio de la transacción, como siempre; se deshace toda la transacción.
    Hay que tener en cuenta que cuando se deshace una transacción hasta un punto de almacenamiento, SQL Server no libera los recursos bloqueados. Se liberan cuando se confirma la transacción o al producirse una cancelación de toda la transacción.
    Para especificar un punto de almacenamiento en una transacción se utiliza la instrucción siguiente:

    SAVE TRAN[SACTION] nombre

    Se añade de un punto de almacenamiento en la transacción en la posición hasta la que se desea deshacer. Para deshacer hasta el punto de almacenamiento hay que utilizar ROLLBACK TRAN con el nombre del punto de almacenamiento, como se muestra a continuación:

    ROLLBACK TRAN nombre: Se pueden tener más instrucciones de T-SQL después de la instrucción ROLLBACK para continuar la transacción. Hay que recordar incluir una instrucción COMMIT u otra instrucción ROLLBACK después de la primera instrucción ROLLBACK para que se complete toda la transacción.