Está en la página 1de 10

LUIS ROJAS Y RUSBEL

PROCEDIMIENTOS ALMACENADOS
--listar todos los títulos y su correspondiente autor

CREATE PROCEDURE listarTitulosAutores


AS
BEGIN
SELECT titles.title, authors.au_fname, authors.au_lname
FROM titles
JOIN titleauthor ON titles.title_id = titleauthor.title_id
JOIN authors ON titleauthor.au_id = authors.au_id
ORDER BY titles.title ASC
END

--Buscar títulos por tipo y precio

CREATE PROCEDURE buscarTitulosPorTipoPrecio


@tipo VARCHAR(20),
@precio FLOAT
AS
BEGIN
SELECT title, price
FROM titles
WHERE type = @tipo AND price < @precio
END

--Actualizar el precio de un título

CREATE PROCEDURE actualizarPrecioTitulo


@titulo VARCHAR(80),
@precio FLOAT
AS
BEGIN
UPDATE titles
SET price = @precio
WHERE title = @titulo
END

--Eliminar un autor y sus títulos relacionados


CREATE PROCEDURE eliminarAutorYTItulosRelacionados
@id_autor VARCHAR(11)
AS
BEGIN
DELETE FROM titleauthor
WHERE au_id = @id_autor

DELETE FROM titles


WHERE title_id IN (
SELECT title_id
FROM titleauthor
WHERE au_id = @id_autor
)

DELETE FROM authors


WHERE au_id = @id_autor
END
--Listar los 10 autores con más títulos publicados

CREATE PROCEDURE listarAutoresMasProductivos


AS
BEGIN
SELECT TOP 10 authors.au_fname, authors.au_lname, COUNT(*) AS total
FROM authors
JOIN titleauthor ON authors.au_id = titleauthor.au_id
GROUP BY authors.au_fname, authors.au_lname
ORDER BY total DESC
END

--insertar un nuevo título y sus autores

CREATE PROCEDURE insertarTituloYAutores


@titulo VARCHAR(80),
@tipo VARCHAR(20),
@precio FLOAT,
@au_ids VARCHAR(255)
AS
BEGIN
BEGIN TRANSACTION

DECLARE @id_titulo VARCHAR(6)


EXECUTE dbo.nuevo_id_titulo @id_titulo OUTPUT

INSERT INTO titles (title_id, title, type, price)


VALUES (@id_titulo, @titulo, @tipo, @precio)

DECLARE @au_id VARCHAR(11)


DECLARE @posicion INT

WHILE CHARINDEX(',', @au_ids) > 0


BEGIN
SELECT @posicion = CHARINDEX(',', @au_ids)
SELECT @au_id = SUBSTRING(@au_ids, 1, @posicion-1)

INSERT INTO titleauthor (title_id, au_id)


VALUES (@id_titulo, @au_id)

SELECT @au_ids = STUFF(@au_ids, 1, @posicion, '')


END

INSERT INTO titleauthor (title_id, au_id)


VALUES (@id_titulo, @au_ids)

COMMIT TRANSACTION
END

--Obtener el número total de ventas de un título:

CREATE PROCEDURE obtenerVentasTitulo


@titulo VARCHAR(80)
AS
BEGIN
SELECT SUM(qty)
FROM sales
WHERE title_id = (
SELECT title_id
FROM titles
WHERE title = @titulo
)
END
--Buscar autores por nombre y estado:

CREATE PROCEDURE buscarAutoresPorNombreEstado


@nombre VARCHAR(40),
@estado VARCHAR(2)
AS
BEGIN
SELECT *
FROM authors
WHERE au_fname LIKE '%' + @nombre + '%'
AND state = @estado
END
--Actualizar la información de un autor:

CREATE PROCEDURE actualizarAutor


@id_autor VARCHAR(11),
@nombre VARCHAR(40),
@apellido VARCHAR(40),
@telefono CHAR(12),
@direccion VARCHAR(40),
@ciudad VARCHAR(20),
@estado VARCHAR(2),
@codigo_postal CHAR(5),
@pais VARCHAR(20),
@contrato BIT
AS
BEGIN
UPDATE authors
SET au_fname = @nombre,
au_lname = @apellido,
phone = @telefono,
address = @direccion,
city = @ciudad,
state = @estado,
zip = @codigo_postal,
country = @pais,
contract = @contrato
WHERE au_id = @id_autor
END
--Listar los títulos que no tienen ventas:

CREATE PROCEDURE listarTitulosSinVentas


AS
BEGIN
SELECT titles.title
FROM titles
LEFT JOIN sales ON titles.title_id = sales.title_id
WHERE sales.qty IS NULL
END
--
--FUNCIONES CON VALOR DE TABLA

--OBTENER TODOS LOS AUTORES Y SUS TÍTULOS


CREATE FUNCTION autoresYTitulos()
RETURNS @resultados TABLE (
au_id VARCHAR(11),
au_nombre VARCHAR(40),
au_apellido VARCHAR(40),
titulo VARCHAR(80),
tipo VARCHAR(20),
precio FLOAT
)
AS
BEGIN
INSERT INTO @resultados
SELECT authors.au_id, authors.au_fname, authors.au_lname, titles.title,
titles.type, titles.price
FROM authors
JOIN titleauthor ON authors.au_id = titleauthor.au_id
JOIN titles ON titleauthor.title_id = titles.title_id

RETURN
END

--Obtener los títulos vendidos por año

CREATE FUNCTION titulosMasVendidosPorAnio(@anio INT)


RETURNS @resultados TABLE (
titulo VARCHAR(80),
ventas_totales INT
)
AS
BEGIN
INSERT INTO @resultados
SELECT TOP 5 titles.title, SUM(sales.qty)
FROM titles
JOIN sales ON titles.title_id = sales.title_id
WHERE YEAR(sales.ord_date) = @anio
GROUP BY titles.title
ORDER BY SUM(sales.qty) DESC

RETURN
END

--Obtener los autores que han vendido más de 100,000 dólares en un año
CREATE FUNCTION autoresMasVendedoresPorAnio(@anio INT)
RETURNS @resultados TABLE (
au_id VARCHAR(11),
au_nombre VARCHAR(40),
au_apellido VARCHAR(40),
ventas_totales FLOAT
)
AS
BEGIN
INSERT INTO @resultados
SELECT TOP 5 authors.au_id, authors.au_fname, authors.au_lname, SUM(sales.qty *
titles.price)
FROM authors
JOIN titleauthor ON authors.au_id = titleauthor.au_id
JOIN titles ON titleauthor.title_id = titles.title_id
JOIN sales ON titles.title_id = sales.title_id
WHERE YEAR(sales.ord_date) = @anio
GROUP BY authors.au_id, authors.au_fname, authors.au_lname
HAVING SUM(sales.qty * titles.price) > 100000
ORDER BY SUM(sales.qty * titles.price) DESC

RETURN
END

--Obtener los autores con más títulos publicados


CREATE FUNCTION autoresMasProductivos()
RETURNS @resultados TABLE (
au_id VARCHAR(11),
au_nombre VARCHAR(40),
au_apellido VARCHAR(40),
titulos_publicados INT
)
AS
BEGIN
INSERT INTO @resultados
SELECT TOP 5 authors.au_id, authors.au_fname, authors.au_lname,
COUNT(titles.title_id)
FROM authors
JOIN titleauthor ON authors.au_id = titleauthor.au_id
JOIN titles ON titleauthor.title_id = titles.title_id
GROUP BY authors.au_id, authors.au_fname, authors.au_lname
ORDER BY COUNT(titles.title_id) DESC

RETURN
END

--Obtener los títulos más vendidos de un autor


CREATE FUNCTION titulosMasVendidosPorAutor(@id_autor VARCHAR(11))
RETURNS @resultados TABLE (
titulo VARCHAR(80),
ventas_totales INT
)
AS
BEGIN
INSERT INTO @resultados
SELECT TOP 5 titles.title, SUM(sales.qty)
FROM authors
JOIN titleauthor ON authors.au_id = titleauthor.au_id
JOIN titles ON titleauthor.title_id = titles.title_id
JOIN sales ON titles.title_id = sales.title_id
WHERE authors.au_id = @id_autor
GROUP BY titles.title
ORDER BY SUM(sales.qty) DESC

RETURN
END
--consultas que utilizan un trigger en la base de datos pubs
--Registrar cambios en la tabla "sales" en otra tabla "sales_hisoty"

CREATE TRIGGER tr_sales_history ON sales


AFTER INSERT, UPDATE, DELETE
AS
BEGIN
IF EXISTS(SELECT * FROM inserted)
BEGIN
INSERT INTO sales_history (title_id, stor_id, ord_num, qty, payterms,
sales_date, sale_type)
SELECT i.title_id, i.stor_id, i.ord_num, i.qty, i.payterms, GETDATE(), 'I'
FROM inserted i
END

IF EXISTS(SELECT * FROM deleted)


BEGIN
INSERT INTO sales_history (title_id, stor_id, ord_num, qty, payterms,
sales_date, sale_type)
SELECT d.title_id, d.stor_id, d.ord_num, d.qty, d.payterms, GETDATE(), 'D'
FROM deleted d
END
END

--Este trigger registra los cambios en la tabla "sales" en la tabla "sales_history",


agregando una fila por cada inserción, actualización o eliminación. La columna
"sale_type" indica si la fila es una inserción ('I') o una eliminación ('D').
--2 ACTUALIZAR EL PRECIO DE UN LIBRO EN LA TABLA "TITLES" CUANDO SE ACTUALIZA SU
TIPO DE
--LIBRO EN LA TABLA "PUB_INFO"
CREATE TRIGGER tr_actualizar_precio_base ON pub_info
AFTER UPDATE
AS
BEGIN
IF UPDATE (type)
BEGIN
UPDATE titles
SET price = CASE pub_info.type
WHEN 'business' THEN titles.price * 1.1
WHEN 'mod_cook' THEN titles.price * 0.9
ELSE titles.price
END
FROM titles
JOIN pub_info ON titles.pub_id = pub_info.pub_id
JOIN inserted ON inserted.pub_id = pub_info.pub_id
WHERE titles.type = inserted.type
END
END

--Este trigger actualiza el precio base de un libro en la tabla "titles" cuando se


actualiza su tipo de libro en la tabla "pub_info". El nuevo precio se calcula
multiplicando el precio original por 1.1 si el nuevo tipo es "business" o por 0.9 si
el nuevo tipo es "mod_cook".
--3 VERIFICAR QUE LOS VALORES DE LA COLUMNA "PRICE" EN LA TABLA "TITLES
--SEAN MAYORES A 0
CREATE TRIGGER tr_verificar_precio ON titles
AFTER INSERT, UPDATE
AS
BEGIN
IF EXISTS(SELECT * FROM inserted WHERE price <= 0)
BEGIN
ROLLBACK TRANSACTION
RAISERROR ('El precio debe ser mayor a cero.', 16, 1)
END
END

--Este trigger verifica que los valores de la columna "price" en la tabla "titles"
sean mayores a 0 durante una inserción o actualización. Si un valor menor o igual a
0 es detectado, la transacción es revertida y se muestra un mensaje de error.
--4 RESTRINGIR LA ELIMINACIÓN DE UN AUTOR QUE TENGA TÍTULOS ASOCIADOS
-- EN LA TABLA "TITLEAUTHOR"
CREATE TRIGGER tr_restringir_eliminar_autor ON authors
INSTEAD OF DELETE
AS
BEGIN
IF EXISTS(SELECT * FROM deleted d JOIN titleauthor ta ON d.au_id = ta.au_id)
BEGIN
RAISERROR ('No se puede eliminar un autor que tiene títulos asociados.', 16,
1)
ROLLBACK TRANSACTION
END
ELSE
BEGIN
DELETE FROM authors WHERE au_id IN (SELECT au_id FROM deleted)
END
END
--Este trigger restringe la eliminación de un autor que tenga títulos asociados en
la tabla "titleauthor". Si se encuentra algún título asociado al autor a eliminar,
se muestra un mensaje de error y se revierte la transacción. Si no hay títulos
asociados, se permite la eliminación del autor
--5 ACTUALIZAR LA CANTIDAD DE TÍTULOS EN LA TABLA "PUBLISHERS" CUANDO SE INSERTA O
ELIMINA UNA FILA EN LA TABLA "TITLES"
CREATE TRIGGER tr_actualizar_cant_titulos ON titles
AFTER INSERT, DELETE
AS
BEGIN
UPDATE publishers
SET pub_info = REPLACE(pub_info, 'Cantidad de títulos: ' + CAST((SELECT COUNT(*)
FROM titles WHERE pub_id = publishers.pub_id) AS varchar), 'Cantidad de títulos: ' +
CAST((SELECT COUNT(*) FROM inserted WHERE pub_id = publishers.pub_id) AS varchar))
FROM publishers
JOIN inserted ON inserted.pub_id = publishers.pub_id OR deleted.pub_id =
publishers.pub_id
END
--CONSULTAS UTILIZANDO EL CURSOR EN LA BASE DE DATOS PUBS
--1 OBTENER EL NÚMERO TOTAL DE VENTAS DE CADA LIBRO EN LA TABLA "SALES" Y MOSTRAR EL
RESULTADO
--EN UN TABLA
DECLARE @title_id VARCHAR(20), @qty INT, @total_sales MONEY

DECLARE cur_sales CURSOR FOR


SELECT title_id, qty FROM sales

CREATE TABLE #sales_summary


(
title_id VARCHAR(20),
total_sales MONEY
)

OPEN cur_sales

FETCH NEXT FROM cur_sales INTO @title_id, @qty

WHILE @@FETCH_STATUS = 0
BEGIN
SET @total_sales = @qty * (SELECT price FROM titles WHERE title_id = @title_id)
IF EXISTS (SELECT * FROM #sales_summary WHERE title_id = @title_id)
BEGIN
UPDATE #sales_summary SET total_sales = total_sales + @total_sales WHERE
title_id = @title_id
END
ELSE
BEGIN
INSERT INTO #sales_summary (title_id, total_sales) VALUES (@title_id,
@total_sales)
END
FETCH NEXT FROM cur_sales INTO @title_id, @qty
END

CLOSE cur_sales
DEALLOCATE cur_sales

SELECT * FROM #sales_summary

--Este código utiliza un cursor para recorrer la tabla "sales" y calcular el número
total de ventas de cada libro multiplicando la cantidad vendida por el precio de
cada libro. Los resultados se almacenan en una tabla temporal llamada
"#sales_summary" y se muestran al final
--2 OBTENER EL NÚMERO DE AUTORES DE CADA EDITORIAL EN LA TABLA "PUBLISHER" Y MOSTRAR
EL RESULTADO EN UN TABLA
DECLARE @pub_id VARCHAR(4), @au_id VARCHAR(11)

DECLARE cur_authors CURSOR FOR


SELECT pub_id, au_id FROM titleauthor

CREATE TABLE #authors_summary


(
pub_id VARCHAR(4),
num_authors INT DEFAULT 0
)

OPEN cur_authors

FETCH NEXT FROM cur_authors INTO @pub_id, @au_id

WHILE @@FETCH_STATUS = 0
BEGIN
IF EXISTS (SELECT * FROM #authors_summary WHERE pub_id = @pub_id)
BEGIN
UPDATE #authors_summary SET num_authors = num_authors + 1 WHERE pub_id =
@pub_id
END
ELSE
BEGIN
INSERT INTO #authors_summary (pub_id, num_authors) VALUES (@pub_id, 1)
END
FETCH NEXT FROM cur_authors INTO @pub_id, @au_id
END

CLOSE cur_authors
DEALLOCATE cur_authors

SELECT * FROM #authors_summary

--Este código utiliza un cursor para recorrer la tabla "titleauthor" y contar el


número de autores de cada editorial en la tabla "publishers". Los resultados se
almacenan en una tabla temporal llamada "#authors_summary" y se muestran al final.
--3 UTILIZAR UN CURSOR PARA MOSTRAR LOS TITULOS Y SUS PRECIOS DE LA TABLA "TITLES"
DECLARE @title_id varchar(20), @price money
DECLARE cur_titles CURSOR FOR
SELECT title_id, price FROM titles
OPEN cur_titles
FETCH NEXT FROM cur_titles INTO @title_id, @price
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'Título: ' + @title_id + ', Precio: ' + CAST(@price AS varchar)
FETCH NEXT FROM cur_titles INTO @title_id, @price
END
CLOSE cur_titles
DEALLOCATE cur_titles

--Este cursor recorre la tabla "titles" y muestra los títulos y sus precios
utilizando un bucle WHILE y la función PRINT.
--4 UTILIZAR UN CURSOR PARA ACTUALIZAR EL PRECIO DE LOS TITULOS DE LA EDITORIAL "NEW
MOON BOOKS" EN UN 10%
DECLARE @title_id varchar(20), @price money
DECLARE cur_titles CURSOR FOR
SELECT title_id, price FROM titles WHERE pub_id = '0877'
OPEN cur_titles
FETCH NEXT FROM cur_titles INTO @title_id, @price
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE titles SET price = @price * 1.1 WHERE title_id = @title_id
FETCH NEXT FROM cur_titles INTO @title_id, @price
END
CLOSE cur_titles
DEALLOCATE cur_titles
--Este cursor recorre la tabla "titles" y actualiza el precio de los títulos de la
editorial "New Moon Books" en un 10% utilizando un bucle WHILE y la sentencia
UPDATE.
--5 UTILIZAR UN CURSOR PARA CALCULAR EL TOTAL DE VENTAS DE CADA AUTOR Y MOSTRARLOS
EN ORDEN DESCENDENTE
DECLARE @au_id varchar(20), @total_sales money
DECLARE cur_sales CURSOR FOR
SELECT au_id, SUM(qty * price) AS total_sales FROM sales JOIN titleauthor ON
sales.title_id = titleauthor.title_id GROUP BY au_id
OPEN cur_sales
FETCH NEXT FROM cur_sales INTO @au_id, @total_sales
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT 'Autor: ' + @au_id + ', Total de ventas: ' + CAST(@total_sales AS varchar)
FETCH NEXT FROM cur_sales INTO @au_id, @total_sales
END
CLOSE cur_sales
DEALLOCATE cur_sales

---Este cursor utiliza una consulta que une las tablas "sales" y "titleauthor" para
calcular el total de ventas de cada autor y mostrarlos en orden descendente
utilizando un bucle WHILE y la función PRINT.

También podría gustarte