SQL_Server.
md 2024-10-02
Curso de SQL Server
Autor: Juan Sebastian Mora Fuente: Youtube Channel
Comandos de base de datos
Crear base de datos
CREATE DATABASE NOMBRE_BASE_DATOS;
Seleccionar objetos del gestor
SELECT * FROM [Link];
-- Selecciona todas las bases de datos
Modificar base de datos
ALTER DATABASE NOMBRE_BASE_DATOS MODIFY NAME = Principal;
Tipos de datos
--Tipos de datos
char -- almacenar tipos de datos de ancho fijo
varchar -- almacena tipos de datos alfanúmericos de ancho variable
text -- almacena tipos de datos texto
nchar -- almacena tipos de datos de ancho fijo
nvarchar -- almacena tipos de datos alfanúmericos de ancho variable
bit -- almacena valores de 1 y 0
int -- almacena valores entre -2,147,483,648, y 2,147,483,637
bigint -- almacena valores entre -9,223,372,036,854,775,808 y
9,223,372,036,854,775,807
decimal -- almacena valores entre -10^38 + 1 y 10^38 - 1
numeric -- almacena valores entre -10^38 + 1 y 10^38 - 1
money -- almacena valores entre -9,223,372,036,854,775,808 y
9,223,372,034,854,775,807
float -- almacena valores entre -1.79E + 308 y 1.79E + 308
Comandos con tablas
1 / 53
SQL_Server.md 2024-10-02
Crear tabla
CREATE TABLE EMPLEADOS(
idEmpleado int,
Nombre varchar(20),
Apellido varchar(30),
Edad numeric(2),
telefono numeric(10),
direccion varchar(100),
fechaNacimiento date,
salario decimal(18,2),
activo char(2)
);
Mostrar todas las tablas de la base de datos
SELECT * FROM [Link];
Recolectar campos
SELECT idEmpleado, Nombree
FROM EMPLEADOS;
Cambiar el nombre de las tablas mediante un SP (Store procedure)
EXEC sp_rename 'EMPLEADOS','USUARIOS';
-- Se deben modificar los objetos que usan esa tabla
Borrar tabla
DROP TABLE NOMBRE_TABLA;
Limpiar tabla
TRUNCATE TABLE EMPLEADOS;
DELETE FROM EMPLEADOS
WHERE idEmpleado=7;
DELETE FROM EMPLEADOS;
2 / 53
SQL_Server.md 2024-10-02
DELETE FROM a diferencia del TRUNCATE TABLE permite realizar filtros o eliminar todo
Agregar columna
ALTER TABLE EMPLEADOS
ADD SEXO CHAR(1);
Eliminar Columna
ALTER TABLE EMPLEADOS
DROP COLUMN fecha_contratacion;
ALTER TABLE EMPLEADOS
DROP COLUMN SEXO;
Cambiar nombre de columna
EXEC SP_RENAME '[Link]','id';
-- Verificar los objetos de la base de datos
exec sp_rename '[Link]' , 'NOMBRE';
exec sp_rename '[Link]' , 'APELLIDO';
exec sp_rename '[Link]' , 'EDAD';
exec sp_rename '[Link]' , 'TELEFONO';
exec sp_rename '[Link]' , 'DIRECCION';
exec sp_rename '[Link]' , 'FECHA_NACIMIENTO';
exec sp_rename '[Link]' , 'SALARIO';
exec sp_rename '[Link]' , 'ACTIVO';
Actualizar registros
UPDATE EMPLEADOS
SET NOMBRE = 'Cristiano'
WHERE id = 3;
Insertar registros
INSERT INTO SALARIOS(NOMBRE,APELLIDO,SALARIO)
SELECT NOMBRE,APELLIDO,SALARIO FROM EMPLEADOS WHERE SALARIO > 2500;
Clausula Where
3 / 53
SQL_Server.md 2024-10-02
SELECT * FROM EMPLEADOS
WHERE NOMBRE='Jorge';
SELECT * FROM EMPLEADOS
WHERE EDAD=29;
SELECT NOMBRE,EDAD
FROM EMPLEADOS
WHERE EDAD=29;
Operadores
Operadores permitidos:
Mayor - Menos: < >
Igual - No Igual: = !=
Mayor o igual: >=
Menor o igual: <=
-- <>, !=, <,>, =,<=,>=
SELECT * FROM EMPLEADOS WHERE idEmpleado = 3;
-- != or <>
SELECT * FROM EMPLEADOS WHERE Edad != 25;
-- <= or >=
SELECT * FROM EMPLEADOS WHERE salario >=2000;
-- < or >
SELECT * FROM EMPLEADOS WHERE salario < 2500;
Comentarios
-- Comentario de una línea
/*
Comentario multilínea
*/
NULOS
CREATE TABLE CLIENTES(
IDCLIENTE INT,
NOMBRE VARCHAR(10),
APELLIDO VARCHAR(20),
DIRECCION VARCHAR(100)
);
4 / 53
SQL_Server.md 2024-10-02
La tabla CLIENTES permite nulos en sus columnas. Filtrar nulos
-- Filtro nulo
SELECT * FROM CLIENTES
WHERE NOMBRE IS NULL; -- Nombre sea nulo
SELECT * FROM CLIENTES
WHERE NOMBRE IS NOT NULL; -- Nombre no sea nulo
SELECT * FROM CLIENTES
WHERE DIRECCION IS NULL; -- Dirección sea nula
Configurar las tablas para evitar o permitir nulos
CREATE TABLE CLIENTES(
IDCLIENTE INT NOT NULL,
NOMBRE VARCHAR(10) NOT NULL,
DIRECCION VARCHAR(100) NOT NULL,
TELEFONO NUMERIC(10) NULL,
EMAIL VARCHAR(50) NULL
);
-- Inserción de nulo
INSERT INTO CLIENTES VALUES(1,'Jose','Calle Primera',NULL,'email@[Link]');
CONSTRAINTS
Los CONSTRAINTS son reglas que tienen y se le pueden agregar a las tablas para seguir unas normas y evitar
posibles errores.
CREATE TABLE PERSONAS(
IDPERSONA INT PRIMARY KEY,
NOMBRE VARCHAR(10) NOT NULL,
EDAD INT NOT NULL
);
Se agrega un constraint por defecto, que no permite duplicados en el campo idpersona, ya que es clave
primaria de la tabla.
Constraint personalizado
CREATE TABLE PERSONAS(
IDPERSONA INT,
NOMBRE VARCHAR(10) NOT NULL,
EDAD INT NOT NULL,
5 / 53
SQL_Server.md 2024-10-02
CONSTRAINT PK_ENLACE_PERSONA PRIMARY KEY (IDPERSONA)
);
De esta manera el CONSTRAINT se agrega con el nombre PK_ENLACE_PERSONA como PRIMARY KEY, indicando
que el campo idpersona es clave primaria. Agregar Constraint mediante alter table
ALTER TABLE PERSONAS
ADD CONSTRAINT PK_ENLACE PRIMARY KEY (IDPERSONA);
Cuando un campo no cuenta con CONSTRAINT, se le puede adicionar uno aun asi ya exista la tabla. Eliminar
constraint mediante alter table
ALTER TABLE PERSONAS
DROP CONSTRAINT PK_ENLACE;
En este caso mediante ALTER TABLE se eliminan los constraint enlazados a los campos de las tablas. UNIQUE
CONSTRAINT
-- Version 1 (por defecto)
CREATE TABLE PERSONAS(
idpersona int not null unique,
nombre varchar(10),
edad int
);
-- Version 2 (Directo)
DROP TABLE PERSONAS;
CREATE TABLE PERSONAS(
idpersona int not null,
nombre varchar(10),
edad int,
CONSTRAINT UQ_idpersona unique(idpersona)
);
-- Version 3 (Alter table)
DROP TABLE PERSONAS;
CREATE TABLE PERSONAS(
idpersona int not null,
nombre varchar(10),
edad int
);
ALTER TABLE PERSONAS
ADD CONSTRAINT UD_idpersona unique(idpersona);
-- Borrar constraint
6 / 53
SQL_Server.md 2024-10-02
ALTER TABLE PERSONAS
DROP CONSTRAINT UD_idpersona;
Permite valores unicos en los campos, útil en la creación de identificadores únicos en las tablas, similar a los
números de celular, cédulas, etc.
CHECK CONSTRAINT Limitar el rango de valores permitidos en una columna
DROP TABLE PERSONAS;
CREATE TABLE PERSONAS(
ID INT NOT NULL,
NOMBRE VARCHAR(10),
EDAD INT,
CHECK (EDAD>=18) -- SOLO PERMITE REGISTROS CON EDAD >=18
);
INSERT INTO PERSONAS VALUES(1,'JUAN',18);
SELECT * FROM PERSONAS;
INSERT INTO PERSONAS VALUES(2,'LUIS',15); -- No permite inserción
UPDATE PERSONAS SET EDAD=15 WHERE EDAD=18; -- No permite actualización
-- Version 1
DROP TABLE PERSONAS;
CREATE TABLE PERSONAS(
ID INT NOT NULL,
NOMBRE VARCHAR(10),
EDAD INT CHECK (EDAD>=18) -- dentro de la misma columna
);
-- Version 2
DROP TABLE PERSONAS;
CREATE TABLE PERSONAS(
ID INT NOT NULL,
NOMBRE VARCHAR(10),
EDAD INT,
CONSTRAINT CK_EDAD CHECK(EDAD>=18) -- Constraint personalizado
);
-- Version 3
DROP TABLE PERSONAS;
CREATE TABLE PERSONAS(
ID INT NOT NULL,
NOMBRE VARCHAR(10),
EDAD INT
);
ALTER TABLE PERSONAS
ADD CONSTRAINT CK_EDAD CHECK(EDAD>=18);
7 / 53
SQL_Server.md 2024-10-02
-- Eliminar constraint
ALTER TABLE PERSONAS
DROP CONSTRAINT CK_EDAD;
DEFAULT CONSTRAINT Usada para establecer un valor por defecto en una columna, en caso de no agregarle
un valor.
-- Version 1
DROP TABLE PERSONAS;
CREATE TABLE PERSONAS(
ID INT NOT NULL,
NOMBRE VARCHAR(10),
EDAD INT,
CIUDAD VARCHAR(50) DEFAULT 'No Tiene'
);
INSERT INTO PERSONAS VALUES (1,'JUAN',18,default);
SELECT * FROM PERSONAS; -- No tiene debido al campo default
-- Version 1
DROP TABLE PERSONAS;
CREATE TABLE PERSONAS(
ID INT NOT NULL,
NOMBRE VARCHAR(10),
EDAD INT,
CIUDAD VARCHAR(50),
CONSTRAINT DF_CIUDAD DEFAULT 'No Tiene' FOR CIUDAD
);
-- Version 3
DROP TABLE PERSONAS;
CREATE TABLE PERSONAS(
ID INT NOT NULL,
NOMBRE VARCHAR(10),
EDAD INT,
CIUDAD VARCHAR(50)
);
ALTER TABLE PERSONAS
ADD CONSTRAINT DF_CIUDAD DEFAULT 'No Tiene' FOR CIUDAD;
-- Borrar constraint
ALTER TABLE PERSONAS
DROP CONSTRAINT DF_CIUDAD;
IDENTITY CONSTRAINT Aumenta su campo a medida que va recibiendo inserts, igual que crear una
secuencia.
8 / 53
SQL_Server.md 2024-10-02
CREATE TABLE LIBROS(
CODIGO INT IDENTITY,
TITULO VARCHAR(60) NOT NULL,
AUTOR VARCHAR(60) NOT NULL
);
INSERT INTO LIBROS VALUES('Cien años de soledad','Gabriel García Marquez');
select * from libros;
-- Si elimino un registro, no se vuelve a generar esa secuencia.
DROP TABLE LIBROS;
CREATE TABLE LIBROS(
CODIGO INT IDENTITY(10,2), -- Inicia en 10 y salta en 1
TITULO VARCHAR(60) NOT NULL,
AUTOR VARCHAR(60) NOT NULL
);
En caso de querer averiguar el inicio de un campo o el incremento usamos:
SELECT IDENT_SEED('LIBROS'); -- Ver valor inicial del campo identity
SELECT IDENT_INCR('LIBROS'); -- Ver valor de incremento
SET IDENTITY_INSERT LIBROS ON; -- Activar la inserción manual
SET IDENTITY_INSERT LIBROS OFF; -- Desactivar la inserción manual
FOREIGN KEY Relacionar tablas mediante llaves foraneas, generando relaciones:
1:1
1:*
*:1
*:*
DROP TABLE CLIENTES;
CREATE TABLE CLIENTES(
ID_CLIENTE INT,
NOMBRE VARCHAR(20) NOT NULL,
APELLIDO VARCHAR(30) NOT NULL,
EDAD INT NOT NULL
CONSTRAINT PK_CLIENTES PRIMARY KEY (ID_CLIENTE)
);
DROP TABLE ORDENES;
CREATE TABLE ORDENES(
ID_ORDEN INT NOT NULL,
ARTICULO VARCHAR(50) NOT NULL,
ID_CLIENTE INT
CONSTRAINT FK_ORDENES_CLIENTES FOREIGN KEY REFERENCES CLIENTES(ID_CLIENTE)
);
9 / 53
SQL_Server.md 2024-10-02
En este casoo la tabla ordenes depende la llave foranea ID_CLIENTE, por lo cual siempre que existe una
orden debera tener un cliente. A su vez un cliente puede tener muchas ordenes.
En caso de borrar un registro donde este tenga un campo relacionado en otra tabla, un cliente que ya
esta en ordenes, no se podra borrar porque viola la regla, se debería primero borrar las relaciones
BORRADO EN CASCADA En solución a lo anterior, se puede activar un borrado en cascada que borra a su
vez las relaciones pero esto puede causar borrados innecesarios por lo cual se debe manejar con cuidado
DROP TABLE CLIENTES;
CREATE TABLE CLIENTES(
ID_CLIENTE INT,
NOMBRE VARCHAR(20) NOT NULL,
APELLIDO VARCHAR(30) NOT NULL,
EDAD INT NOT NULL
CONSTRAINT PK_CLIENTES PRIMARY KEY (ID_CLIENTE)
);
DROP TABLE ORDENES;
CREATE TABLE ORDENES(
ID_ORDEN INT NOT NULL,
ARTICULO VARCHAR(50) NOT NULL,
ID_CLIENTE INT
CONSTRAINT FK_ORDENES_CLIENTES FOREIGN KEY REFERENCES CLIENTES(ID_CLIENTE)
ON DELETE CASCADE -- Permite borrado en cascada.
);
Borrar foreign key
ALTER TABLE ORDENES
DROP CONSTRAINT FK_ORDENES_CLIENTES;
Vistas
Son tablas virtuales basadas en una consulta, pueden materializarse.
CREATE VIEW CLIENTES_NACIONALES
AS
SELECT * FROM CLIENTES;
CREATE VIEW MAYORES_30
AS
SELECT NOMBRE,APELLIDO,TELEFONO,EDAD
FROM CLIENTES
WHERE EDAD>30;
10 / 53
SQL_Server.md 2024-10-02
Útil en consultas demasiado frecuentes
Modificar vista
ALTER VIEW MAYORES_30
AS
SELECT
NOMBRE,APELLIDO,TELEFONO,EDAD,FECHA_NACIMIENTO
FROM CLIENTES
WHERE EDAD>30;
Eliminar vista
DROP VIEW MAYORES_30;
Indices
Estructuras utilizadas para mejorar el rendimiento de las consultas
SQL Server cuenta con dos tipos:
Clustered
Nonclustered
Clustered:
CREATE CLUSTERED INDEX I_IDEMPLEADO
ON EMPLEADOS (ID);
Nonclustered:
CREATE NONCLUSTERED INDEX I_EDAD
ON EMPLEADOS (EDAD);
Renombrar indice
EXEC SP_RENAME 'EMPLEADOS.I_IDEMPLEADO','I_ID','INDEX';
Eliminar indice
DROP INDEX I_ID ON EMPLEADOS;
11 / 53
SQL_Server.md 2024-10-02
Indice agrupado
CREATE CLUSTERED INDEX I_ID_SAL
ON EMPLEADOS (ID,SALARIO);
DISTINCT
Me retorna los valores sin repetir de una variable
SELECT DISTINCT PAIS FROM CLIENTES;
Alias
Mediante el uso de la palabra reservada as
SELECT ID AS Identificador, NOMBRE as "primer nombre", APELLIDO, SALARIO
FROM EMPLEADOS
WHERE SALARIO < 3000;
Concatenación
Mediante el símbolo +
SELECT NOMBRE +' '+ APELLIDO AS "Nombre Completo"
FROM EMPLEADOS;
Casteo
Útil para cambio de formatos en valores con diferentes formatos o formatos que requeridos a la salida.
SELECT NOMBRE+' '+APELLIDO+' '+CAST(EDAD AS VARCHAR(2))
FROM EMPLEADOS;
Mediante la función CAST().
Operaciones
Las operaciones básicas +,-,*,/,% se encuentran en SQL y función de la misma forma que en otros lenguajes
de programación.
12 / 53
SQL_Server.md 2024-10-02
SELECT (30-12);
SELECT NOMBRE, DESCRIPCION, PRECIO + (PRECIO*0.1) AS "Nuevo Precio"
FROM ARTICULOS;
SELECT NOMBRE, DESCRIPCION, PRECIO - (PRECIO*0.1) AS "Descuento 10%"
FROM ARTICULOS;
SELECT nombre,descripcion, precio*cantidad AS precio_total
FROM ARTICULOS;
SELECT NOMBRE, DESCRIPCION, PRECIO*VENDIDOS AS ventas_total
FROM ARTICULOS;
SELECT NOMBRE, DESCRIPCION, CANTIDAD - VENDIDOS AS STOCK
FROM ARTICULOS;
Esquemas
En SQL Server se maneja por defecto el esquema DBO, es decir un conjunto que asocia las bases de datos al
esquema DBO, sin embaro, este puede personalizarse a las caracteristicas requeridas por la base de datos.
Crear esquema
CREATE SCHEMA VENTAS; -- Creación esquema
CREATE SCHEMA COBROS; -- Creación 2do esquema
Administración de permisos mediante esquemas
-- Creación de tablas asociadas a un esquema
CREATE TABLE [Link](
IDCLIENTES INT,
NOMBRE VARCHAR(10),
DIRECCION VARCHAR(30)
);
CREATE TABLE [Link](
IDCLIENTES INT,
NOMBRE VARCHAR(10),
DIRECCION VARCHAR(30)
);
-- Eliminación de tablas asociadas a un esquema
DROP TABLE [Link];
13 / 53
SQL_Server.md 2024-10-02
Restaurar base de datos
Debido al versionamiento en SQL Server, se deben tener una versión compatible en el gestor. Para revisar la
versión de SQL Server.
SELECT @@VERSION;
Para restaurarla se puede hacer mediante el gestor de bases de datos, dando clic derecho en Databases y
luego dar clic en Restaurar base de datos
ORDER BY
SELECT * FROM EMPLEADOS ORDER BY ID;
SELECT * FROM EMPLEADOS ORDER BY EDAD ASC;
Funciones
MAX - MIN
SELECT
MAX(PRECIO) AS "Producto mas caro",
MIN(PRECIO) AS "Producto mas barato",
MAX(Nombre) AS "Ordenado alfabeticamente max",
MIN(Nombre) AS "Ordenado alfabeticamente min"
FROM articulos;
COUNT
SELECT COUNT(1) AS CANTIDAD FROM EMPLEADOS;
SELECT COUNT(1) AS "Emplados asistentes"
FROM EMPLEADOS
WHERE PUESTO = 'Asistente';
SUM
SELECT SUM(SUELDO) AS "Salario Total"
FROM EMPLEADOS;
AVG
14 / 53
SQL_Server.md 2024-10-02
SELECT AVG(SUELDO) AS "Salario promedio por Gerente"
FROM EMPLEADOS
WHERE PUESTO = 'Gerente';
SELECT AVG(DISTINCT(SUELDO)) AS "Salario promedio por valores distintos"
FROM EMPLEADOS;
Operadores
Útiles para operaciones lógicas, se pueden encontrar:
AND
OR
NOT
SELECT * FROM CLIENTES
WHERE PAIS = 'Italia' AND CIUDAD = 'Roma';
SELECT * FROM CLIENTES
WHERE CIUDAD = 'Venecia' OR CIUDAD = 'Roma';
SELECT * FROM CLIENTES
WHERE NOT PAIS = 'Alemania';
Between A diferencia de la función IN esta cuenta dentro de un rango y no valores únicos.
SELECT * FROM EMPLEADOS
WHERE id_empleado IN(1,3,5,7); -- 1,3,5 Y 7
-- SE DIFERENCIAN EN EL RANGO DE VALORES QUE TOMAN
SELECT * FROM EMPLEADOS
WHERE id_empleado BETWEEN 1 AND 7; -- De 1 a 7
SELECT * FROM EMPLEADOS
WHERE SUELDO BETWEEN 2000 AND 4000
AND PUESTO NOT IN ('Desarrollador');
Between tipo texto Funciona tambien con valores textuales en orden alfabetico
SELECT * FROM CLIENTES
WHERE PAIS BETWEEN 'Alemania' AND 'Canada'
ORDER BY PAIS;
Between fechas
15 / 53
SQL_Server.md 2024-10-02
SELECT * FROM EMPLEADOS
WHERE FECHA_CONTRATACION BETWEEN '1996-07-01' AND '2003-05-06';
Operador LIKE & NOT LIKE
Algunas funcionalidades del operador se le conocen como wildcards que son útiles para ejecución de
funciones regulares y condiciones.
SELECT * FROM clientes
WHERE NOMBRE LIKE 'A%';
-- Empieza con A
SELECT * FROM clientes
WHERE NOMBRE LIKE '_A%';
-- A Como segundo caracter
SELECT * FROM clientes
WHERE NOMBRE LIKE 'A%O';
-- Empieza con A y termina con O
JOIN
16 / 53
SQL_Server.md 2024-10-02
Enlaces entre tablas:
INNER JOIN JOIN por defecto se entiende como INNER JOIN
SELECT ORDENES.id_orden, [Link]
FROM ORDENES
INNER JOIN CLIENTES
ON [Link] = [Link]
WHERE NOMBRE = 'Juan'
ORDER BY FECHA_ORDEN;
LEFT JOIN Todos los que esten en la izquierda asi no esten en la derecha.
SELECT [Link],[Link],O.ID_ORDEN
FROM CLIENTES C
LEFT JOIN ORDENES O
ON [Link] = [Link]
ORDER BY id_orden;
RIGHT JOIN Preferencia por la derecha.
17 / 53
SQL_Server.md 2024-10-02
select ord.id_orden, [Link], [Link]
from clientes cli
right join ordenes ord
on [Link]=[Link]
order by ord.id_orden;
FULL JOIN Muestra todas las filas entre las 2 sin coincidencias. Enlace completo.
select ord.id_orden, [Link], [Link]
from clientes cli
full join ordenes ord
on [Link]=[Link]
order by ord.id_orden;
UNION Se deben tener las mismas columnas en los select y deben ser de los mismos tipos cada una.
SELECT 'Cliente' as Tipo,CONTACTO,CIUDAD,PAIS FROM CLIENTES
UNION
SELECT 'Suplidor' as Tipo,CONTACTO,CIUDAD,PAIS FROM SUPLIDORES
ORDER BY PAIS;
-- UNA ENCIMA DE OTRA, diferenciando cuales son suplidores y cuales clientes
GROUP BY
SELECT COUNT(IDCLIENTE) AS "No. Clientes", PAIS
FROM CLIENTES
GROUP BY PAIS
ORDER BY "No. Clientes" DESC;
SELECT max(IDCLIENTE) AS "Id. Maximo", PAIS
FROM CLIENTES
GROUP BY PAIS
ORDER BY "Id. Maximo" DESC;
SELECT AVG(IDCLIENTE) AS "Id. Promedio", PAIS
FROM CLIENTES
GROUP BY PAIS
ORDER BY "Id. Promedio" DESC;
SELECT [Link], COUNT([Link]) AS "Cantidad de ordenes"
FROM ORDENES O
LEFT JOIN VENDEDOR VE
ON VE.id_vendedor = O.id_vendedor
GROUP BY [Link];
18 / 53
SQL_Server.md 2024-10-02
Función HAVING Permite realizar una condición a grupos.
El Where de los grupos
SELECT COUNT(IDCLIENTE) AS CANTIDAD,PAIS
FROM CLIENTES
GROUP BY PAIS
HAVING COUNT(IDCLIENTE) > 5
-- Necesita especificar la agrupación, no se puede poner solo alias
ORDER BY CANTIDAD DESC;
-- EJ 2: Cantidades de ordenes superiores a 5 por vendedor
SELECT [Link] AS Vendedor, COUNT([Link]) AS "Cantidad ordenes"
FROM ORDENES O
JOIN VENDEDOR V
ON O.id_vendedor = V.id_vendedor
GROUP BY [Link]
HAVING COUNT([Link]) > 5;
Subconsultas
Debe ir entreparéntesis
Especificar solo una columna o expresion
Usar con IN, ANY, ALL y EXISTS
No pueden contener Between ni like, no pueden contener order by o usar update/delete
create table facturas(
numero int not null,
fecha datetime,
cliente varchar(30),
primary key(numero)
);
create table detalles(
numerofactura int not null,
numeroitem int not null,
articulo varchar(30),
precio decimal(5,2),
cantidad int,
primary key(numerofactura,numeroitem),
constraint FK_detalles_numerofactura
foreign key (numerofactura)
references facturas(numero)
on update cascade
on delete cascade
);
-- Cuales empleados ganan mas o igual al salario promedio
19 / 53
SQL_Server.md 2024-10-02
SELECT ID_EMPLEADO,NOMBRE,APELLIDO,SUELDO
FROM EMPLEADOS WHERE SUELDO >=(SELECT AVG(sueldo)
FROM EMPLEADOS)
-- Buscar todos los nombres de clientes con idcliente de México
SELECT NOMBRE, CIUDAD FROM CLIENTES
WHERE IDCLIENTE IN (SELECT idcliente FROM Clientes
WHERE pais = 'México');
-- Otra forma clausula ANY
SELECT NOMBRE, CIUDAD FROM CLIENTES
WHERE IDCLIENTE = ANY (SELECT idcliente FROM Clientes
WHERE pais = 'México');
Clausula EXISTS, NOT EXISTS Buscar coincidencias en una subconsulta, any busca cualquier coincidencia,
pero EXISTS es mas específico.
SELECT cliente, numero, fecha
FROM facturas f
WHERE EXISTS (SELECT * FROM detalles d
WHERE [Link] = [Link]
AND [Link] = 'Lápiz');
NULOS
Funciones para el control de datos nulos, reemplazan su valor por algo mas.
ISNULL()
SELECT nombre,precio_unidad,ISNULL(vendidos,0) AS vendidos
FROM productos;
-- ISNULL me ayuda a reemplazar los nulos por algun valor deseado (debe ser del
mismo formato)
SELECT nombre, precio_unidad * ISNULL(existencia + vendidos, 0) AS Ganancia
FROM productos;
COALESCE()
-- COALESCE tambien me permite reemplazar nulos
SELECT nombre,precio_unidad,COALESCE(vendidos,0) AS vendidos
FROM productos;
CASE
20 / 53
SQL_Server.md 2024-10-02
Dependiendo de un evento generar un resultado diferente:
Ejemplo:
1. Ver articulos de mi inventario con existencia normal
2. Ver articulos que necesitan ser pedidos
3. Ver articulos menos vendidos
SELECT nombre,cantidad,
CASE
WHEN cantidad > 30 then 'Articulo con sobre-existencia'
WHEN cantidad < 10 then 'Se debe realizar pedido'
ELSE 'Existencia normal'
END AS Inventario
FROM ARTICULOS;
Ejemplo: Generar un nombre con nombre, pais y ciudad de los clientes organizar el reporte por ciudad,
en caso de que el cliente no tenga ciudad, organizar por país.
SELECT nombre,pais,ciudad
FROM clientes
ORDER BY
(CASE
WHEN ciudad IS NULL THEN pais
ELSE ciudad);
Es decir se organiza por ciudad, pero si encuentra un nulo organiza por país hasta que encuentre una
ciudad nula. Se organiza dinamicamente.
FUNCIONES MATEMÁTICAS
Función PI( )
SELECT PI() AS PI;
Función de redondeo de cifras CEILING( )
SELECT CEILING($123.1) AS 'numero redondeado';
Redondea al entero mayor y no afecta usar valores de tipo money
SELECT ceiling(-123.1) AS 'numero redondeado negativo',ceiling(123.1) AS 'numero
redondeado';
21 / 53
SQL_Server.md 2024-10-02
En números negativos elimina los decimales pero no redondea, los convierte en enteros.
Función FLOOR( ) para eliminar decimales
SELECT floor(123.45), floor(-123.45);
Los decimales positivos solo le quita los decimales, es decir, los vuelve enteros. Los decimales negativos los
redondea al número mas negativo.
Función ROUND( )
SELECT ROUND(123.453,2),ROUND(123.5,0),ROUND(123.5,1);
Redondea y se le puede agregar los decimales que quiera aproximar, sin embargo no quita los decimales, en
el ejemplo anterior queda 123.450, con .5 hacia arriba aproxima al número más grande. Sino aproxima con
los decimales que se tiene deja el número como esta, es decir, ROUND(123.45,3) pasa a ser 123.45 ya que el
tercer decimal sería 0 en este caso.
Función POWER( ) Potenciación
SELECT POWER(4,2),POWER(8,3);--4^2,8^3
Función RAND( ) Valor entre 0-1 (decimales)
SELECT RAND(),RAND()*(100-1),RAND()*(1-100);
En este caso el segundo me da un valor entre 0 y 99. El tercero un valor de 0 y -99 (1-100)=-99.
Seed: La función RAND() se le puede agregar una semilla para que los datos permanezcan siempre
igual de la siguiente forma RAND(45), en este caso 45 sería la semilla y mientras este todos los valores
random no cambiaran aleatoriamente.
Función SIN( ) y COS( )
SELECT SIN(90) AS SENO,COS(90) AS COSENO;
Tambien podemos encontrar:
sin(angle) – It returns sine of the specified angle in radians float value
asine(sine) – It returns the angle of the sine value in radians float value.
cos(angle) – It returns the cosine of the specified angle in radians float value.
22 / 53
SQL_Server.md 2024-10-02
acos(cos) – It returns the angle of the cosine in radians float value.
cot(angle) – It returns the cotangent of the specified angle in radians float value.
tan(angle) – It returns the tangent of the given angle and it returns a float value.
atan(tangent) – It returns the angle in radians of the given tangent float value.
atn2(x,y) – It returns the angle in radians between the positive x-axis and the ray from the origin to the
point (y, x). Here x and y are float values.
FUENTE>
Función SQRT( ) Raiz cuadrada
SELECT SQRT(64) AS 'Raiz cuadrada';
FUNCIONES DE FECHA - DATE
Fecha y hora del sistema
SELECT GETDATE() AS FECHA; --Obtener fecha / hora sistema
Agregar fecha función DATEADD( ): suma temporal en campos temporales
SELECT DATEADD(DAY,1,GETDATE()) AS MAÑANA;
SELECT DATEADD(MONTH,1,GETDATE()) AS 'en 1 mes';
SELECT DATEADD(DAY,-1,GETDATE()) AS AYER;
SELECT DATEADD(YEAR,1,GETDATE()) AS 'en 1 año';
SELECT DATEADD(HOUR,3,GETDATE()) AS 'en 3 horas';
NOTA: útil para rangos de fechas, en este caso 1 año de diferencia.
SELECT * FROM FACTURAS
WHERE FECHA BETWEEN '2018-01-01'
AND DATEADD(YEAR,1,'2018-01-01');
SELECT * FROM FACTURAS
WHERE FECHA BETWEEN '2023-01-01'
AND DATEADD(MONTH,3,'2023-01-01');
SELECT * FROM FACTURAS
WHERE FECHA BETWEEN '2023-06-28'
AND DATEADD(DAY,10,'2023-06-28');
Obtener nombre de la fecha, función DATENAME( )
23 / 53
SQL_Server.md 2024-10-02
-- Dame el nombre de la fecha
SELECT DATENAME(MONTH,GETDATE()); --En este caso obtenemos el mes
-- Para cambiarle el idioma a español
SET LANGUAGE SPANISH;
SELECT DATENAME(MONTH,GETDATE()); -- Ahora si me lo vota en español
-- Si quiero solo el número en vez del nombre
SELECT DATEPART(MONTH,GETDATE()) AS MES;
-- Para días se modifica para el día de la semana.
SELECT 'Hoy es: '+DATENAME(WEEKDAY,GETDATE()) AS 'Día de la semana';
DATEPART devuelve un número
Ejemplo: Dame las facturas del mes actual.
SELECT CLIENTE, FECHA, DATENAME(MONTH,FECHA) AS MES
FROM FACTURAS
WHERE DATENAME(MONTH,FECHA) = DATENAME(MONTH,GETDATE());
FUNCIONES STRING
Función CHAR( ): Saber el valor de un carácter de acuerdo a una posición
SELECT CHAR(50) AS LETRA; --CHAR(50):2
SELECT NOMBRE +' '+ CHAR(65) FROM EMPLEADOS; --CHAR(65):A
Función CONCAT( ): para unir valores separados con comas
SELECT CONCAT('Hola','a','todos') as saludo;
SELECT CONCAT('Feliz',' cumpleaños ',11,' / ','25') as felicitación;
Función LEN( ): número de carácteres (incluido espacios)
SELECT LEN('SQLServer'),LEN(10);
Función LOWER( ),UPPER( ):
SELECT LOWER('HOLA') as minusculas,UPPER('hola') as mayusculas;
Hacer la primera en mayuscula:
24 / 53
SQL_Server.md 2024-10-02
SELECT CONCAT(UPPER(left('hola a todos',1)),
lower(right('hola a todos',len('hola a todos')-1))) as 'solo la
primera mayuscula';
Función TRIM(): Recorta espacios a izquierda, derecha y ambos lados
-- FUNCIÓN TRIM: Recorta espacios a izquierda y derecha
SELECT TRIM(' Hola papus ')+' fin';
-- FUNCIÓN LTRIM: Recorta espacios a la izquierda
SELECT LTRIM(' Hola papus ')+' fin';
-- FUNCIÓN RTRIM: Recorta espacios a la derecha
SELECT RTRIM(' Hola papus ')+' fin';
Función REPLACE(): Reemplaza el texto
SELECT REPLACE('El cocobongo','oc','a');
Función TRANSLATE(): necesita tener la misma cantidad de caracteres a reemplazar.
SELECT TRANSLATE('abcdefb','abc','010');
Reemplaza letra por letra según el criterio puesto en este caso todas las a con 0. Todas las b con 1 y
todas las c con 0
SELECT TRANSLATE('[123.4,72.23]','[,]','( )') AS Cambio;
-- Cambie los corchetes por parentésis y las comas por puntos.
Función REPLICATE( ): Replicar los caracteres/texto dentro de un campo con una cantidad determinada
SELECT REPLICATE('0',6),REPLICATE('Hola',3),REPLICATE(1,3);
Función REVERSE( ): Al revez la entrada
SELECT REVERSE('ALOH') AS HOLA,
REVERSE('SQLSERVER') AS ALCONTRARIO,
REVERSE(1234) AS 'Reverso numeros';
FUNCIÓN LEFT( ) y RIGHT( ):
25 / 53
SQL_Server.md 2024-10-02
LEFT: De la izquierda a derecha devuelve un determinado número de caracteres
RIGHT: De la derecha a izquierda devuelve un determinado número de caracteres
No admite negativos
SELECT LEFT(EMAIL,2),RIGHT(EMAIL,2) FROM E_MAILS;
SELECT RIGHT(EMAIL,11) AS CORREO
FROM E_MAILS ORDER BY CORREO DESC;
Función STUFF( ): Eliminar cantidad de caracteres desde un punto especifico, lo reemplaza por un argumento
enviado.
SELECT STUFF('Hola a todos',3,5,'Amigos') AS SALUDO;
-- Salida: HoAmigostodos
TRANSACT-SQL:
Extensión de SQL, programación de SQL (T-SQL)
Función BULK INSERT: Permite carga eficiente de datos desde un archivo especifico externo a una tabla
BULK INSERT
AUTOS -- Tabla destino
FROM 'C:\Users\sebas\Downloads\TABLA_AUTOS.txt' -- Tabla fuente
WITH (FIRSTROW = 2); --Desde que fila arrancan los datos
CLAUSULA OVER( )
Se utiliza en combinación con funciones de agrupación. Cálculo de valores basados en funciones ya definidas.
select id_orden, fecha_orden, monto_total, id_cliente,
sum(monto_total) over() as Total --la sumatoria total en una columna Total
from ordenes;
select id_orden, fecha_orden, monto_total, id_cliente,
avg(monto_total) over() as Average --el promedio total en una columna Average
from ordenes;
PARTITION BY( )
Parámetro usado en funciones de agrupamiento para dividir el conjunto en particiones en una o mas
columnas
26 / 53
SQL_Server.md 2024-10-02
-- promedio por cada departamento
SELECT idempleado,nombre,puesto,iddepartamento,salario,
avg(salario) over(partition by iddepartamento) as "salario promedio dep."
from empleados;
-- promedio por cada puesto
SELECT idempleado,nombre,puesto,iddepartamento,salario,
sum(salario) over(partition by puesto) as "salario total por puesto"
from empleados;
-- % salario de c/empleado sobre el total de su departamento
SELECT idempleado,nombre,puesto,iddepartamento,salario,
concat(left(round(100*salario/sum(salario) over(partition by iddepartamento),
2),
4),
' %')
as "% Salario Total"
from empleados;
Ejemplo de salida del tercer query
Función RANK( ) Función de ventana, agrupación que asigna un rango en c/fila de un connjunto de
resultados ordenados según una o mas columnas especificas. Antes de aplicar a función RANK(), los datos se
ordenan según las columnas especificadas en la cláusula ORDER BY La función RANK() asigna un rango a
c/fila basándose en el orden de los datos despues de la ordenación
select idempleado,nombre,puesto,iddepartamento,salario,
RANK() OVER(ORDER BY salario desc) AS 'Top Salarios'
from empleados;
select idempleado,nombre,puesto,iddepartamento,salario,
DENSE_RANK() OVER(ORDER BY salario desc) AS 'Top Salarios'
from empleados;
ROW_NUMBER( ) y FIRST_VALUE( ) Ambas necesitan OVER()
SELECT ROW_NUMBER() OVER(ORDER BY A.VEN_ULT_ANIO DESC) AS CONTADOR,
[Link], A.VEN_ULT_ANIO FROM VENTAS A;
Le agrega una columna contador que va de acuerdo a la cantidad de ventas del ultimo año en orden
descendente
27 / 53
SQL_Server.md 2024-10-02
Aplicandole una subconsulta:
SELECT IDVENDEDOR, VEN_ULT_ANIO FROM (
SELECT ROW_NUMBER() OVER(ORDER BY A.VEN_ULT_ANIO DESC) AS CONTADOR,
[Link], A.VEN_ULT_ANIO FROM VENTAS A) AS SUBCONSULTA
WHERE CONTADOR = 1;
FIRST_VALUE: Retorna el primer valor del conjunto
SELECT * FROM VENTAS A
WHERE [Link] = (
SELECT
DISTINCT FIRST_VALUE(IDVENDEDOR) OVER(ORDER BY VEN_ULT_ANIO DESC) AS
CONTADOR
FROM VENTAS AS V);
Máximo salario de tabla salarios
SELECT NOMBRE,APELLIDO,SALARIO FROM
(SELECT
ROW_NUMBER() OVER(ORDER BY SALARIO DESC) AS Ranking,
NOMBRE,
APELLIDO,
SALARIO
FROM SALARIOS) AS SUBCONSULTA
WHERE RANKING = 1;
Ejemplo con first_value
SELECT * FROM SALARIOS
WHERE
NOMBRE+' '+APELLIDO = (
SELECT
DISTINCT FIRST_VALUE(NOMBRE +' '+APELLIDO) OVER(ORDER BY SALARIO DESC) AS
MAX_SAL_EMP
FROM SALARIOS);
BLOQUES / INTRO
Contienen las siguientes secciones:
DECLARE
VARIABLE 1
28 / 53
SQL_Server.md 2024-10-02
VARIABLE 2
...
VARIABLE X
BEGIN
CODIGO PRINCIPAL
IF-ELSE
RETURN
WAITFOR
WHILE
CASE
CONTINUE
FOR
DO WHILE
CONTROL DE EVENTUALIDADES (SUBSECCION)
END
IF-ELSE Ejemplo: Cuantos articulos tienen existencia 0
IF EXISTS(SELECT * FROM ARTICULOS WHERE CANTIDAD = 0) -- Si se cumple...
(SELECT NOMBRE, PRECIO, CANTIDAD
FROM ARTICULOS
WHERE CANTIDAD = 0)
ELSE -- Si no se cumple...
SELECT 'NO HAY ARTICULOS EN 0' AS Resultado;
Ejemplo: con una tabla
CREATE TABLE PRUEBA(
CAMPO1 INT,
CAMPO2 INT);
-- Revisar el objeto con id prueba
SELECT * FROM [Link]
WHERE NAME = 'PRUEBA';
-- Si el objeto con id prueba tiene valores retorna algo, borra la tabla
IF OBJECT_ID('PRUEBA') IS NOT NULL
DROP TABLE PRUEBA;
Ver asientos disponibles en cada sala, en caso de no haber asientos desplegar mensaje de entradas agotadas
if exists (select * from cartelera where capacidad > entradas)
(select sala, pelicula, hora, (capacidad - entradas) as 'Disponible(s)'
from cartelera
where capacidad > entradas)
else
29 / 53
SQL_Server.md 2024-10-02
select 'Entradas agotadas!' as resultado;
-- Verificar el else...
UPDATE CARTELERA SET capacidad = entradas
WHERE capacidad > entradas;
VARIABLES Comienza siempre con el simbolo "@" seguido del nombre:
@variable1
@cantidad_
Recomendado: combinanciones alfanumericas. Son utilizadas en La sección declare, donde se crea su
declaración. En este caso se le debe definir su tipo: int, varchar, date...
Al momento de declararse estas llevan un valor nulo. esperando a ser inicializadas.
declare
@id_valor int,
-- inicialización desde declare (opcional: declarar constantes)
@nombre varchar(20) = 'Hola',
@telefono numeric(10),
@fecha_nac date,
@activo bit;
begin
-- inicialización desde el begin
set @id_valor = 50;
select @id_valor,@nombre;
set @nombre = 'Chao';
set @telefono = 3108618222;
set @fecha_nac = '1999/12/30';
set @activo = 1; --puede set 'true','false',0,#>0
select @nombre,@telefono,@fecha_nac,@activo;
end;
Ejemplo:
-- Ejemplo:
declare
@codigo int = 10;
begin
select * from articulos
where codigo = @codigo;
end;
-- Ejemplo 2: usandolo dentro de un like
declare
@patron varchar(20);
begin
set @patron = '%Lap%';
select * from articulos
30 / 53
SQL_Server.md 2024-10-02
where nombre like @patron;
end;
Ejemplo: Inicializando una variable desde un select
declare
@mayorprecio decimal(6,2);
begin
-- inicializo = max(precio)
select @mayorprecio = max(precio)
from articulos;
-- busco el registro con el precio = @mayorprecio = max(precio)
select * from articulos
where precio = @mayorprecio;
end;
Variables de tipo tabla No es necesario usar begin y end, sin embargo, no se almacena como un objeto
"tabla" sino como una variable de tipo tabla. Se deben hacer sus ejecuciones directamente en el declare
declare
@tabla1 table (
id int,
nombre varchar(20),
telefono numeric(10)
);
insert into @tabla1 values(1,'Juan',12312314);
select * from @tabla1;
-- Si ejecuto lo siguiente solo... No funcionaria porque ya no toma la variable
tipo tabla por tanto @tabla1 no existiría.
select * from @tabla1;
STORE PROCEDURE / PROCEDIMIENTOS ALMACENADOS
Conjunto de instrucciones y comandos que se guardan como objeto en nuestra base de datos con el fin de
guardar tareas repetitivas. Tenemos algunos que se almacenan en la base de datos master. Los cuales llevan
un prefijo sp_ como el sp_rename. Existen 3 tipos:
locales: del usuario y se eliminan apenas cierre sesion.
temporales: usan el signo #
globales: quedan disponibles para todas las sesiones de usuarios usan el signo ##
Ejemplo: Ver todos los articulos que tengan menos de 20 unidades de existencia
create proc = create procedure
31 / 53
SQL_Server.md 2024-10-02
create proc p_existencia
as
select * from articulos
where cantidad < 20;
-- Ejecución
exec p_existencia
Una vez ejecutado lo podemos observar en el explorador de objetos de la base de datos en el apartado de
programmability / store procedures. Para ejecutar se usa lo siguiente:
Ejemplo 2:
create procedure p_actualiza_inventario
as
-- actualización -> bloque de sentencias
-- lógica de programación -> bloque de sentencia
begin
if exists(select * from articulos
where cantidad < 10)
update articulos set cantidad = 15
where cantidad < 10;
end;
-- Ejecución
EXEC p_actualiza_inventario;
Ejemplo 3:
create proc p_bonificacion
as
begin
if exists(select * from empleados where cant_hijos > 3)
begin
update empleados set sueldo = sueldo*0.20 where cant_hijos > 3;
print 'Se ha aplicado la bonificación!';
end;
else
begin
print 'No hay empleados con mas de 3 hijos';
end;
end;
-- Ejecución
exec p_bonificación;
Mofificar un procedimiento almacenado
32 / 53
SQL_Server.md 2024-10-02
alter procedure p_bonificacion
as
begin
if exists(select * from empleados where cant_hijos > 1)
begin
update empleados set sueldo = sueldo*2 where cant_hijos > 1;
print 'Se ha aplicado la bonificación!';
end;
else
begin
print 'No hay empleados con mas de 3 hijos';
end;
end;
Borrar un procedimiento almacenado
DROP PROCEDURE p_existencia;
SP con parámetros de entrada
create procedure p_busca_emple
@nombre varchar(30) = 'Carlos'
as
select * from empleados where nombre = @nombre;
Modificar al momento de crearlo
create or alter procedure p_busca_emple
@nombre varchar(30) = 'Juan'
as
select * from empleados where nombre = @nombre;
-- Ejecución
exec p_busca_emple;
-- Ejemplo 2
CREATE OR ALTER PROC P_BUSCA_EMPLE_2
@nombre varchar(30) = 'Ana',
@sueldo int = 900.00,
@hijos int = 1
as
select * from empleados
where nombre = @nombre and sueldo = @sueldo and cant_hijos = @hijos;
Procedimientos almacenados con parámetros de salida
33 / 53
SQL_Server.md 2024-10-02
CREATE OR ALTER PROC P_PROMEDIO
@VALOR1 NUMERIC(6,2),
@VALOR2 NUMERIC(6,2),
@RESULTADO NUMERIC(6,2) OUTPUT
AS
SELECT @RESULTADO = (@VALOR1 + @VALOR2) / 2;
DECLARE
@PROMEDIO NUMERIC(6,2)
EXEC P_PROMEDIO 1234.20,6548.15,@promedio output -- le paso a promedio el
resultado
select @promedio as promedio; -- llamo a la var promedio
Se necesita una declaración para poder usar el sp con parámetros de salida
-- EJEMPLO: Calculo del salario promedio...
CREATE OR ALTER PROCEDURE P_EMPL_SAL_PROMEDIO
@PUESTO VARCHAR(30) = '%',
-- Trae cualquier campo que coincida con el parametro en el like
@SUMA NUMERIC(6,2) OUTPUT,
@PROMEDIO NUMERIC(6,2) OUTPUT
AS
SELECT * FROM EMPLEADOS WHERE PUESTO LIKE @PUESTO
SELECT @SUMA = SUM(SUELDO) FROM empleados
WHERE PUESTO LIKE @PUESTO
SELECT @PROMEDIO = AVG(SUELDO) FROM empleados
WHERE PUESTO LIKE @PUESTO;
-- EJECUCION
DECLARE
@SUMATORIA NUMERIC(6,2),
@PROM NUMERIC(6,2)
EXEC P_EMPL_SAL_PROMEDIO 'Desarrollador',@sumatoria output,@prom output
SELECT @SUMATORIA AS TOTAL,@PROM AS PROMEDIO;
Me trae la suma y promedio del sueldo de un Desarrollador.
OBJETOS DEL SISTEMA
Todos los procedimientos almacenados
SELECT * FROM SYSOBJECTS;
¿Comó podemos hacer que otros usuarios no puedan ver el contenido de un SP propio?
Podemos ver el código de un sp de la siguiente forma:
34 / 53
SQL_Server.md 2024-10-02
EXEC SP_HELPTEXT NOMBRE_SP;
Para bloquear esta función necesitamos activar un parámetro de encriptación con la siguiente instrucción
with encryption. Encriptación
create or alter procedure p_bonificacion
with encryption -- bloqueando visualización
as
begin
if exists(select * from empleados where cant_hijos > 1)
begin
update empleados set sueldo = sueldo*2 where cant_hijos > 1;
print 'Se ha aplicado la bonificación!';
end;
else
begin
print 'No hay empleados con mas de 3 hijos';
end;
end;
De esta forma no nos dejará ver el código con el sp sp_helptext.
TABLAS TEMPORALES
Solo existen mientras tenga la sesión activa. Apenas cierre la sesion se eliminaran. Se le crea con un # antes
del nombre. No pueden tener foreign key, ni pueden indexarse sus campos, ni crear una vista de ellas.
CREATE TABLE #USUARIOS(
NOMBRE VARCHAR(10),
CLAVE VARCHAR(10),
PRIMARY KEY(NOMBRE)
);-- No se refleja en el explorador de objetos
INSERT INTO #USUARIOS VALUES('Jose','123453');
-- No se almacenan en una base de datos sino se mantienen globalmente
-- Por lo cual se puede usar desde cualquier base de datos.
Nos sirven para almacenar registros mientras realizamos modificaciones.
FUNCIONES EN SQL SERVER
Bloques de código predefinidos para usar operaciones especificas con nuestros datos. Existen varios tipos:
Funciones de agregado/agrupación: devuelven 1 solo valor.
35 / 53
SQL_Server.md 2024-10-02
sum, avg, count, max, count
Funciones de fila: Operan en c/fila individualmente, para realizar calculos en c/fila a la vez - upper,
lower, substring, dateformat
Clasificación
Funciones deterministicas: retorna el mismo resultado si las generamos con el mismo parámetro de
entrada
No deterministicas: retorna distintos valores c/vez que son llamadas.
getdate, datename, rand
SP: tienen distintos valores, parámetros de entrada y salida.
Escalares: retorna un valor escalar Tabla de varias instrucciones: retorna tabla tabla en linea: retornan una tabla
CREATE OR ALTER FUNCTION f_suma
(@valor1 int, @valor2 int)
returns int
as
begin
declare @resultado int
set @resultado = @valor1 + @valor2
return @resultado
end;
Las podemos encontrar en Programmability/Functions/ depende del tipo, en este caso es scalar.
Ejecución
SELECT dbo.f_suma(5,10) as total;
Es necesario especificar el esquema donde se encuentra la función.
Ejemplo: Meses en español de una fecha
CREATE OR ALTER FUNCTION F_MESES
(@fecha date)
returns varchar(15)
as
begin
declare @mes varchar(15)
set @mes =
case datename(month, @fecha)
when 'January' then 'Enero'
when 'February' then 'Febrero'
when 'March' then 'Marzo'
when 'April' then 'Abril'
when 'May' then 'Mayo'
when 'June' then 'Junio'
36 / 53
SQL_Server.md 2024-10-02
when 'July' then 'Julio'
when 'August' then 'Agosto'
when 'September' then 'Septiembre'
when 'October' then 'Octubre'
when 'November' then 'Noviembre'
when 'December' then 'Diciembre'
end
return @mes
end;
-- Verificación
select datename(month, fecha) as eng_date,dbo.f_meses(fecha) as spa_date, cliente
from facturas;
FUNCIONES DE TIPO TABLA
Ejemplo: Función de tabla que nos diga cuantos libros tenemos de cada autor
CREATE OR ALTER FUNCTION F_AUTOR
(@autor varchar(30))
returns table
as
return (select * from libros where autor like '%'+@autor+'%');
-- Verificación
SELECT * FROM f_autor('Harper');
Se envía como si fuera una tabla la función.
TRIGGERS
Proceso desencadenador. Proceso que se ejecuta cuando ocurre algun evento
Mantienen integridad de los datos
Se usan en tablas o vistas
No se invocan, se ejecutan en automatico apenas percibe el evento configurado
En SQL Server existen 4 tipos:
After Insert: despues de inserción
After Update: despues de actualización
After Delete: despues de eliminación
Instead of: reemplazar una operación original (update, delete, etc) en una función personalizada.
Pueden afectar el rendimiento y operaciones en la base de datos
AFTER INSERT
--TABLAS DE PRUEBA
CREATE TABLE PRUEBA(
37 / 53
SQL_Server.md 2024-10-02
id int null,
nombre varchar(10),
fecha date,
cantidad numeric(3,2)
);
CREATE TABLE CONTROL(
usuario varchar(30),
fecha date,
accion varchar(50)
);
--TRIGGER
CREATE OR ALTER TRIGGER T_INSERTA
ON PRUEBA --TABLA DESTINO
AFTER INSERT
AS
BEGIN
DECLARE @USUARIO VARCHAR(30);
SET @USUARIO = SUSER_NAME(); -- Obtengo usuario del sistema
INSERT INTO CONTROL VALUES(@USUARIO, GETDATE(),'Insert');
END;
-- Funcionamiento
INSERT INTO PRUEBA VALUES(1,'Juancho','2024/07/10',3.52);
-- Verificación
SELECT * FROM PRUEBA; -- Tabla insertada
SELECT * FROM CONTROL; -- Tabla insertada por trigger/disparador
AFTER UPDATE
CREATE OR ALTER TRIGGER T_UPDATE
ON PRUEBA --TABLA DESTINO
AFTER UPDATE
AS
BEGIN
DECLARE @USUARIO VARCHAR(30);
SET @USUARIO = SUSER_NAME(); -- Obtengo usuario del sistema
INSERT INTO CONTROL VALUES(@USUARIO, GETDATE(),'Update');
END;
-- Funcionamiento
UPDATE PRUEBA SET NOMBRE = 'El bicho'
WHERE NOMBRE = 'Juancho';
-- Verificación
SELECT * FROM PRUEBA; -- Tabla insertada
SELECT * FROM CONTROL; -- Tabla insertada por trigger/disparador
AFTER DELETE
CREATE OR ALTER TRIGGER T_DELETE
ON PRUEBA --TABLA DESTINO
38 / 53
SQL_Server.md 2024-10-02
AFTER DELETE
AS
BEGIN
DECLARE @USUARIO VARCHAR(30);
SET @USUARIO = SUSER_NAME(); -- Obtengo usuario del sistema
INSERT INTO CONTROL VALUES(@USUARIO, GETDATE(),'Delete');
END;
-- Funcionamiento
DELETE FROM PRUEBA WHERE NOMBRE = 'El bicho';
-- Verificación
SELECT * FROM PRUEBA; -- Tabla insertada
SELECT * FROM CONTROL; -- Tabla insertada por trigger/disparador
INSERT, UPDATE Y DELETE EN UN MISMO TRIGGER
create table control_empleados(
usuario varchar(30),
fecha date,
hora varchar(20),
accion varchar(50)
);
CREATE OR ALTER TRIGGER T_AUDITORIA
ON EMPLEADOS
FOR INSERT, UPDATE, DELETE
AS
DECLARE @hora VARCHAR(20) = RIGHT(GETDATE(),8);
IF EXISTS(SELECT 0 FROM INSERTED)
-- Verifica algun registro en la tabla virtual 'inserted', si devuelve un dato
significa que ocurrio el insert.
BEGIN
IF EXISTS(SELECT 0 FROM deleted)
-- Revisa si hay registros en la tabla virtual 'deleted'. Ya que en una
actualización los datos se colocan en ambas tablas, los anteriores en deleted y
los nuevos en inserted
BEGIN
INSERT INTO CONTROL_EMPLEADOS VALUES
(SUSER_NAME(),GETDATE(),@HORA,'Actualizó en la tabla empleados');
END;
ELSE
BEGIN
INSERT INTO CONTROL_EMPLEADOS VALUES
(SUSER_NAME(),GETDATE(),@HORA,'Insertó en la tabla empleados');
END;
END;
ELSE
BEGIN
-- Sino inserta solo es posible el borrado
INSERT INTO CONTROL_EMPLEADOS VALUES
(SUSER_NAME(),GETDATE(),@HORA,'Borró en la tabla empleados');
END;
39 / 53
SQL_Server.md 2024-10-02
-- Verificación
SELECT * FROM CONTROL_EMPLEADOS;
SELECT * FROM EMPLEADOS WHERE id_empleado = 41;
-- Funcionamiento
-- insert
INSERT INTO EMPLEADOS
VALUES(41,'Manuel','Gonzales','Direccion X1','Tecnico',700.00,1);
-- update
UPDATE EMPLEADOS SET NOMBRE = 'Pedro'
WHERE id_empleado = 41;
-- delete
DELETE FROM EMPLEADOS WHERE id_empleado = 41;
TRIGGERS DE PREVENCIÓN - INSTEAD OF
Triggers que tienen la función de ejecutarse antes de una insert, update y delete. Usado para crear eventos
preventivos a sucesos no deseables.
INSERT
CREATE OR ALTER TRIGGER TR_BLOCKINSERT_PRODUCTOS
ON PRODUCTOS
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;-- Opcional: bloquear mensaje de salida de datos por consola
INSERT INTO CONTROL_PRODUCTOS
VALUES (SUSER_NAME(),GETDATE(),RIGHT(GETDATE(),8),'Intentó un insert');
print 'NO ES POSIBLE INSERTAR DATOS EN ESA TABLA';
END;
-- Verificación
INSERT INTO PRODUCTOS VALUES (42,'Soldador eléctrico',80.20,4,0);
select * from productos where idproducto = 42;
select * from control_productos;
UPDATE
CREATE OR ALTER TRIGGER TR_BLOCKUPDATE_PRODUCTOS
ON PRODUCTOS
INSTEAD OF UPDATE
AS
BEGIN
SET NOCOUNT ON;-- Opcional: bloquear mensaje de salida de datos por consola
INSERT INTO CONTROL_PRODUCTOS
VALUES (SUSER_NAME(),GETDATE(),RIGHT(GETDATE(),8),'Actualizo un registro');
print 'NO ES POSIBLE ACTUALIZAR DATOS EN ESA TABLA';
END;
40 / 53
SQL_Server.md 2024-10-02
-- Verificación
SELECT * FROM PRODUCTOS;
UPDATE PRODUCTOS SET NOMBRE = 'Prueba' WHERE idproducto = 40;
select * from productos where idproducto = 40;
select * from control_productos;
DELETE
CREATE OR ALTER TRIGGER TR_BLOCKDELETE_PRODUCTOS
ON PRODUCTOS
INSTEAD OF DELETE
AS
BEGIN
SET NOCOUNT ON;-- Opcional: bloquear mensaje de salida de datos por consola
INSERT INTO CONTROL_PRODUCTOS
VALUES (SUSER_NAME(),GETDATE(),RIGHT(GETDATE(),8),'Elimino un registro');
print 'NO ES POSIBLE ELIMINAR DATOS EN ESA TABLA';
END;
-- Verificación
DELETE FROM PRODUCTOS WHERE idproducto = 40;
select * from productos where idproducto = 40;
select * from control_productos;
HABILITAR O INHABILITAR TRIGGERS Debes en cuando es deseable desactivar el trigger para efectuar una
operación, por lo cual podamos volvarlo activarlo despues del cambio. Para hacerlo lo podemos hacer
mediante el parámetro DISABLE TRIGGER con el nombre del trigger sobre la tabla que afecta el trigger.
-- DESABILITAR TRIGGER
ALTER TABLE PRODUCTOS -- tabla con el trigger
DISABLE TRIGGER TR_BLOCKDELETE_PRODUCTOS;
-- EJECUCIÓN
DELETE FROM PRODUCTOS WHERE idproducto = 1;
Deja borrar el producto. Si queremos volverlo a activar para evitar el borrado, usamos el parámetro ENABLE
TRIGGER con el nombre del trigger sobre la tabla que afecta el trigger.
ALTER TABLE PRODUCTOS
ENABLE TRIGGER TR_BLOCKDELETE_PRODUCTOS;
-- EJECUCIÓN
DELETE FROM PRODUCTOS WHERE IDPRODUCTO = 3;
Me salta el error generado por el trigger evitando el borrado
TRIGGER RAISERROR Debes en cuando se desea enviar un mensaje personalizado, para tener presente con
mas detalle el motivo del error. Por lo cual podemos realizarlo con la función RAISERROR('motivo de
41 / 53
SQL_Server.md 2024-10-02
error...') junto con un ROLLBACK TRANSACTION haciendo que los acciones efectuadas en el trigger se
cancelen para tener congruencia.
CREATE OR ALTER TRIGGER TR_BORRA_EMPLEADOS
ON EMPLEADOS
FOR DELETE
AS
IF(SELECT COUNT(1) FROM deleted)>2
BEGIN
RAISERROR('No se puede eliminar mas de dos empleados',16,1);
ROLLBACK TRANSACTION; -- Deshacer el intento de borrado.
END;
-- VERIFICACIÓN
DELETE FROM EMPLEADOS WHERE id_empleado = 1;
-- Si deja borrar porque es solo 1 empleado
DELETE FROM EMPLEADOS WHERE id_empleado IN (5,6,7);
-- Se dispara 1 error por intento de borrar mas de 2 empleados.
Ejemplos con insert y update:
-- update campo
CREATE OR ALTER TRIGGER TR_actualiza_EMPLEADOS
ON EMPLEADOS
FOR UPDATE
AS
IF UPDATE(SUELDO)
BEGIN
RAISERROR('No se puede ACTUALIZAR el SUELDO',16,1);
ROLLBACK TRANSACTION; -- Deshacer el intento de borrado.
END;
SELECT * FROM EMPLEADOS;
UPDATE EMPLEADOS SET SUELDO = 700 WHERE id_empleado = 3;
-- INSERT DATOS
CREATE OR ALTER TRIGGER TR_INSERT_EMPLEADOS
ON EMPLEADOS
FOR INSERT
AS
IF (SELECT PUESTO FROM inserted) = 'Gerente'
BEGIN
RAISERROR('No se puede insertar este puesto',16,1);
ROLLBACK TRANSACTION; -- Deshacer el intento de borrado.
END;
select * from empleados;
INSERT INTO EMPLEADOS
VALUES(41,'Pedro','Gonzales','calle 3','Gerente',1000.00,1);-- Salta error
42 / 53
SQL_Server.md 2024-10-02
BULK INSERT
Inserción masiva desde un archivo externo, pueden ser en formato xlsx, xls, csv, txt, xml.
Para probarlo primero creamos una tabla temporal
-- TABLA DE OBJETOS TEMPORALES
SELECT * FROM [Link];
IF (SELECT NAME FROM [Link]) LIKE '%#BASEPEDIDO%'
drop table #BASEPEDIDO;
CREATE TABLE #BASEPEDIDO(
CodigoPedido VARCHAR(100) NOT NULL,
DocumentoCliente VARCHAR(100) NOT NULL,
CodigoCiudad INT NULL,
CodigoProducto VARCHAR(100) NOT NULL,
CantidadProducto INT,
FechaPedido DATE,
HoraPedido TIME
);
Si existe la tabla, la borra y luego la vuelve a crear.
bulk insert #BASEPEDIDO
from 'C:\Users\sebas\Downloads\[Link]'
with (firstrow = 2) --desde donde esta la data
Nota: el metodo no funciona directamente con formatos excel.
VARIABLES DEL SISTEMA
Dan información sobre la configuración, estado y propiedades del servidor
print 'Version: '+ @@version; -- Version SSMS
print 'Lenguaje: '+ @@language; -- Lenguaje del sistema
print 'Servidor: '+ @@servername; -- Nombre del servidor
print 'Conexiones usuario: '+ str(@@connections); -- Conexiones usuarios
print 'Cantidad maxima de conexiones permitidas: '+str(@@max_connections);
print 'Tiempo en proceso: '+str(@@cpu_busy/60)+' minutos'; -- Funcionamiento
activo desde su inicio
print 'Tiempo inactivo: '+str(@@idle/(3600*24))+' dias'; -- lo devuelve en segs.
print 'Transacciones activas: '+str(@@trancount);
--select * from empleados;
print 'Ultima operación: '+str(@@rowcount); -- Filas afectadas en la ultima
operación.
print 'Ultimo fetch de un cursor: '+str(@@fetch_status);
43 / 53
SQL_Server.md 2024-10-02
print 'Error ultima operación: '+str(@@error);
print 'Ultimo identity: '+str(@@identity); -- Ultimo identity de la secuencia
activa
--create table prueba3(
-- campo1 int identity(1,1),
-- campo2 int null
--);
--insert into prueba3 values (1000);
--select * from prueba3;
print 'Primer dia de la semana: '+str(@@datefirst);
print 'Bloqueo en milisegundos: '+str(@@lock_timeout);
-- configuración de tiempo de espera para bloqueo de la sesión de usuario
-- '-1' significa que no tiene tiempo.
BUCLES / LOOPS / CICLOS
loop [instrucciones] end loop;
while (condition) [instrucciones] end while;
for [rango de valores] [instrucciones]
Pueden usados en cursores: DECLARE nombre_cursor CURSOR FOR [instrucciones] OPEN CURSOR
[instrucciones] FETCH CURSOR [instrucciones] CLOSE CURSOR
While
DECLARE
@CONTEO INT = 0,
@tabla int = 2;
WHILE @CONTEO < 10
BEGIN
--PRINT 'Vuelta número: '+(CONVERT(VARCHAR, @CONTEO));
PRINT
str(@conteo)+') '+(convert(varchar,@tabla)+'*'+
convert(varchar,@conteo)+'='+convert(varchar,@tabla*@conteo));
SET @CONTEO += 1;
END;
While break
DECLARE
@CONTEO1 INT = 0,
@tabla2 int = 20;
WHILE @CONTEO1 <= 12
BEGIN
--PRINT 'Vuelta número: '+(CONVERT(VARCHAR, @CONTEO));
PRINT ('Valor vuelta: '+str(@conteo1));
SET @CONTEO1 += 1;
44 / 53
SQL_Server.md 2024-10-02
IF @CONTEO1 = 7 BREAK;
END;
PRINT 'El valor ya es: '+str(@CONTEO1);
While continue
DECLARE
@VALOR INT = 1;
WHILE @VALOR <= 10
BEGIN
PRINT 'Contando...';
SET @VALOR += 1;
IF @VALOR = 7
PRINT 'El valor ya es: '+str(@valor);
CONTINUE
END;
PRINT 'El valor ya es: '+str(@valor);
Loop anidado
DECLARE
@VALOR1 INT = 1,
@VALOR2 INT = 2;
WHILE @VALOR1 <= 4
BEGIN
PRINT CONCAT('Loop externo: =',@valor1);
WHILE @VALOR2 <= 8
BEGIN
PRINT CONCAT('Loop anidado =',@valor2);
SET @VALOR2+=2;
END;
SET @VALOR1+=1;
END;
Manejo de registros con while
CREATE OR ALTER PROC PR_VER_PRODUCTOS
AS
DECLARE
@CONTEO INT;
SET @CONTEO = (SELECT MAX(IDPRODUCTO) FROM PRODUCTOS);
WHILE @CONTEO > 0
BEGIN
SELECT * FROM PRODUCTOS WHERE IDPRODUCTO = @CONTEO;
SET @CONTEO -= 1;
IF @CONTEO = 1 BREAK;
END;
45 / 53
SQL_Server.md 2024-10-02
-- Ejecución
EXEC PR_VER_PRODUCTOS;
Ejemplo
-- Procedimiento que actualice los datos de mi tabla
CREATE OR ALTER PROC PR_ACTU_PROD
AS
DECLARE @ID INT;
SET @ID = (SELECT MIN(IDPRODUCTO) FROM PRODUCTOS);
WHILE @ID > 0
BEGIN
UPDATE PRODUCTOS SET PRECIO_UNIDAD = PRECIO_UNIDAD*0.9
WHERE idproducto = @ID AND VENDIDOS IS NULL;
SELECT @ID = MIN(IDPRODUCTO) FROM PRODUCTOS
WHERE IDPRODUCTO > @ID AND VENDIDOS IS NULL;
END;
-- Ejecución
EXEC PR_ACTU_PROD;
CURSORES
Recorrer filas y traer resultados de consultas de forma secuencial útiles para cálculos complicados y lógicas de
negocio: tipos:
1. solo lectura
2. actualización
3. inserción
4. combinación
declare
@descripcion numeric(6,2); --variable para los registros
declare --seccion para declarar cursor
prod_info cursor for
select precio_unidad from productos --guardo precio_unidad en prod_info
open prod_info -- abro el cursor
fetch next from prod_info into @descripcion --extracción y salta de reg en
reg.
while @@FETCH_STATUS = 0 --var global que mantiene el estado del ultimo
fetch
begin
print @descripcion --ve imprimiendo lo que va encontrando
fetch next from prod_info into @descripcion --siguiente prod_info
end
close prod_info --cierro cursor (optimizando)
deallocate prod_info --libero recursos asociados al cursor (optimizando)
46 / 53
SQL_Server.md 2024-10-02
Cursor tipo tabla (solo lectura)
declare @id_1 int, @nombre varchar(50), @precios numeric(6,2),@existencia int,
@vendidos int;
declare cu_productos cursor local static read_only for
-- local->solo se aplique en mi sesion
-- static->datos se almacenan en el cursor en el momento en que se abre el cursor
-- read_only->solo lectura
select idproducto,nombre,precio_unidad,existencia,isnull(vendidos,0) from
productos
open cu_productos
fetch next from cu_productos into @id_1,@nombre,@precios,@existencia,@vendidos
while @@FETCH_STATUS = 0
begin
print str(@id_1)+' '+
@nombre+
str(@precios)+
str(@existencia)+
str(@vendidos)
fetch next from cu_productos
into @id_1,@nombre,@precios,@existencia,@vendidos
end;
close cu_productos;
deallocate cu_productos;
NOTA: los nulos los omite por eso ponemos isnull(vendidos,0)
Cursor actualizar datos
-- Ejemplo: Aumento del 10% a las secretarias de la empresa
declare @idempleados int,@aumento_salario numeric(10,2);
declare cu_salarios cursor for
select idempleado, salario from empleados
where puesto = 'Secretaria'
open cu_salarios
fetch next from cu_salarios into @idempleados, @aumento_salario
while @@FETCH_STATUS = 0
begin
set @aumento_salario = @aumento_salario *1.10;
--modifico la variable del salario con el aumento del 10%
update empleados set salario = @aumento_salario
where current of cu_salarios;
--actualizo el campo en el que estoy, la fila actual en ese momento
fetch next from cu_salarios into @idempleados, @aumento_salario;
end;
close cu_salarios;
deallocate cu_salarios;
-- Verifico
select * from empleados where puesto = 'Secretaria';
47 / 53
SQL_Server.md 2024-10-02
USUARIO MODO GRÁFICO
Activar Clic derecho en servidor>properties>security>activate sql server and windows authentication mode
para poder acceder mediante windows (sin contraseña) y con usuario y contraseña
-- Ver esquemas creados
SELECT * FROM [Link];
-- Crear esquema para practica
CREATE SCHEMA PRUEBA2;
Usuario creado por modo gráfico Server>Security>Logins>clic derecho New Login:
Windows authentication para buscar alguno dentro de una red de windows
SQL Server para crear
Ya acá es configuración del usuario.
Server roles los puedes encontrar en microsoft learn para que sirve cada uno.
Permisos para el usuarioEn este caso solo se dio el permiso de connect to sql
En el Object Explorer en los enchufes de X te desconectas y con el de la izquierda te conectas, seleccionas SQL
Server Authentication y pones las credenciales, en este caso puse la opción de cambiar contraseña al iniciar
sesion por primera vez y coloque una nueva contraseña (Olafo051799).
Le dimos permiso solo a la base de datos 'Principal' a la cual accede por defecto, pero las otras no. Esta
opción es 'User Mapping' al momento de crear el usuario. Tambien le asignamos el esquema creado
'PRUEBA2' ya que por defecto accede al dbo. Si trato de acceder a las otras bases de datos me salta error, y
no me permite la visualización de sus tablas. Solo me permite de 'Principal'.
Ejemplo: Al crear un script de SQL y crear una tabla se puede ver en el explorador de objetos que esta tiene
como esquema 'PRUEBA2', el cual fue asignado al momento de crear el usuario
Sin embargo tambien se puede asignar el esquema dbo (defecto) pero toca asignarlo manualmente al
momento de crear la [Link] table [Link](campo1 int not null);
El sistema permite conexión de varios usuarios en el mismo gestor de sql, solo dando clic en connect e inicias
sesión con el otro usuario estos apareceran abajo en el explorador de objetos como otro servidor donde
podras trabajar de manera simultanea con los dos usuarios.
USUARIO SCRIPT
48 / 53
SQL_Server.md 2024-10-02
-- Crear sesion
CREATE LOGIN usuario_Tsql with password = 'Contraseña1234#',
check_expiration = on, --expiración
check_policy = on; --politicas de clave
-- Crear usuario
CREATE USER usuario_Tsql for login Usuario_Tsql --asignandole el login
with default_schema = prueba2 --asignandole el esquema - permite uso de principal
DB
-- Para configurar los roles del usuario
GRANT SELECT ON SCHEMA :: dbo to usuario_Tsql;
-- permiso en todas las tablas del esquema dbo para consultas (SELECT)
GRANT CREATE TABLE TO usuario_Tsql as dbo;
-- creación de tablas en el esquema dbo.
GRANT INSERT, UPDATE, DELETE TO usuario_Tsql;
--GRANT INSERT, UPDATE, DELETE ON tablaX TO usuario_Tsql; para TABLA ESPECIFICA
-- insertar, actualizar y borrar al usuario
-- QUITAR ROLES AL USUARIO
REVOKE INSERT TO usuario_Tsql;
--REVOKE INSERT ON TABLAX TO usuario_Tsql; PARA UNA TABLA ESPECIFICA
JOBS - TRABAJOS
Unidad de trabajo automatica, ejecución de tareas a ciertos eventos y tiempos. Los jobs son una caracteristica
de SQL_server_agent: automatización de tareas administrativas y de mantenimiento de la base de datos. Los
jobs sirven para:
Copia de seguridad y restauración
Reindexación y mantenimiento de índices
Ejecución de Scripts
Generación de informes y notificaciones
Buscar SQL Server 20XX Configuration Manager. En el activar SQL Server Agent (clic derecho y start) debe
aparecer como running > cerrar en el explorador de objetos en el servidor en el SQL Server Agent
Damos clic derecho en jobs > new job, ponemos:
nombre
owner
category En steps ponemos los pasos del job simulando una secuencia damos clic en new step y vamos
agregando los pasos que necesitemos. En este caso le puedes poner el tipo, nombre, db y comando. Lo
hicimos con tipo T-sql y ejecutamos un comando de inserción para el job de insertar datos en
tabla control. En schedules configuras cada tanto quieres que se ejecute, configurando la frecuencia
la hora y demas. El job lo podemos ver y editar en la carpeta de jobs del servidor. En el job activity
monitor podemos ver los jobs que estan trabajando
49 / 53
SQL_Server.md 2024-10-02
BACKUP - RESTAURACIÓN
1era forma: clic derecho en la DB> tasks > back up backup types:
Full: todo
diferential: solo backup de los cambios desde la ultima
transaction_log: todas las transacciones desde un punto de fecha especifico Luego tenemos DB o
[archivos o grupos de archivos (mas flexible)] Luego destino Disk o URL (Remoto)
En Media Options:
Recomendado NO usar Overwrite de los backups
Configuramos si comprimimos o no o el default (recomendado) Luego en la ubicación de la carpeta
tendremos nuestro archivo '.bak' de nuestra base de datos
2da forma: mediante script
backup database STAGE_UPTC
to disk = 'C:\Program Files\Microsoft SQL
50 / 53
SQL_Server.md 2024-10-02
Server\[Link]\MSSQL\Backup\STAGE_UPTC.bak';
Menos configurable
CLAUSULA WITH() - CTE - Consulta como expresion de tabla
Consulta temporal definida en la parte superior de una sentencia, select, insert, update y delete. Permite
dividir la consulta en partes mas pequeñas y lógicas
WITH EmpleadosCTE AS (
SELECT IDEMPLEADO, NOMBRE, PUESTO, IDDEPARTAMENTO, SALARIO
FROM EMPLEADOS
)
SELECT * FROM EmpleadosCTE;
Ejemplos
-- Top 5 salarios ordenados de mayor a menor
WITH Ranking_empleados as (
select idempleado, nombre, puesto, salario,
rank() over(order by salario desc) as 'ranking'
from empleados
)
select * from Ranking_empleados
WHERE ranking <= 5;
-- Top 5 salarios ordenados de mayor a menor (dense_rank)
WITH Ranking_empleados as (
select idempleado, nombre, puesto, salario,
dense_rank() over(order by salario desc) as 'ranking'
from empleados
)
select * from Ranking_empleados
WHERE ranking <= 5;
CONSULTA CRUZADA - CROSS JOIN
Relaciona todos con todos,es decir, de 4 registros en dos tablas relacionaria 1 con 1,2,3 y 4. Luego con el 2 y
asi sucesivamente.
51 / 53
SQL_Server.md 2024-10-02
select [Link],
[Link],
[Link] * [Link] as Precio
from productos
cross join empaques
order by nombre;
ROLLBACK Y COMMIT
Rollback: deshacer una operación - transacción realizadas dentro de una ejecución.
Commit: confirmar y finalizar una transacción como exitosa.
Despues de un commit no se puede revertir las operaciones - transacciones
begin transaction;: Instrucción de inicio de una transacción. se pueden realizar varias operaciones dentro
de la misma, que tome en cuenta todo lo que tenga adentro.
52 / 53
SQL_Server.md 2024-10-02
update empleados set salario = salario * 1.5;
if(select avg(salario) from empleados) >= 10000
begin
rollback transaction; --revertir cambios de la anterior operación (UPDATE)
print 'Ejecución revertida, promedio de \
salarios no cumplen requerimiento';
end;
else
begin
commit transaction;
print 'Salarios actualizados correctamente';--guarde cambios del UPDATE
end;
select * from empleados;
53 / 53