diff --git a/entrega2/entrega2.sql b/entrega2/entrega2.sql new file mode 100644 index 0000000..30e0ee0 --- /dev/null +++ b/entrega2/entrega2.sql @@ -0,0 +1,203 @@ +-- Christopher Cromer - Sección 1 +-- Ignacio Ortiz - Sección 2 + +-- 1 +-- Se usa el año para mostrar los resultados en tal año +-- Si se pasa el valor 0 por el año se muestra por todos los años en vez de un año especifico +CREATE OR REPLACE PROCEDURE CUADRO_HONOR(ANO_IN INTEGER) +IS + V_NOMBRE PAIS.NOMBRE%TYPE; + V_PUNTAJE INTEGER; + + CURSOR C_GANAR IS + SELECT + P2.NOMBRE, + SUM( + CASE + WHEN LOWER(M.DESCRIPCION) = 'oro' THEN + 3 + WHEN LOWER(M.DESCRIPCION) = 'plata' THEN + 2 + WHEN LOWER(M.DESCRIPCION) = 'bronce' THEN + 1 + ELSE + 0 + END + ) AS PUNTAJE + FROM GANAR G + JOIN COMPETER_POR C ON (C.ID_ATLETA = G.ID_ATLETA) + JOIN PERTENECER P ON (P.ID_DELEGACION = C.ID_DELEGACION) + JOIN PAIS P2 ON (P2.ID_PAIS = P.ID_PAIS) + JOIN MEDALLA M ON (M.ID_MEDALLA = G.ID_MEDALLA) + WHERE ( + ANO_IN = + CASE + WHEN ANO_IN != 0 THEN + EXTRACT(YEAR FROM G.FECHA) + ELSE + ANO_IN + END + ) + GROUP BY P2.NOMBRE + ORDER BY PUNTAJE DESC; +BEGIN + OPEN C_GANAR; + FETCH C_GANAR INTO V_NOMBRE, V_PUNTAJE; + DBMS_OUTPUT.PUT_LINE('País' || CHR(9) || CHR(9) || 'Puntaje'); + WHILE C_GANAR%FOUND + LOOP + DBMS_OUTPUT.PUT_LINE(V_NOMBRE || CHR(9) || CHR(9) || V_PUNTAJE); + FETCH C_GANAR INTO V_NOMBRE, V_PUNTAJE; + END LOOP; + CLOSE C_GANAR; +END; +/ + +-- 2 +-- Busca los Lugares una id, suma todas las coincidencias de Precompetencia y Competencia y devuelve la suma +CREATE OR REPLACE PROCEDURE OBTENER_CONTADOR(IDLUGAR IN INTEGER, SUMA OUT INTEGER) +IS + V_ID_PAIS PAIS.ID_PAIS%TYPE; + V_NOMBRE PAIS.NOMBRE%TYPE; + V_CONTADOR INTEGER; + V_SUMA INTEGER DEFAULT 0; + + CURSOR L_PC IS + SELECT L.ID_LUGAR, L.NOMBRE, COUNT(*) AS CONTADOR_PRECOMPETENCIA + FROM PRECOMPETENCIA PC + LEFT JOIN LUGAR L ON (PC.LUGAR = L.ID_LUGAR) + WHERE L.ID_LUGAR = IDLUGAR + GROUP BY (L.ID_LUGAR, L.NOMBRE); + + CURSOR L_C IS + SELECT L.ID_LUGAR, L.NOMBRE, COUNT(*) AS CONTADOR_COMPETENCIA + FROM COMPETENCIA C + LEFT JOIN LUGAR L ON (C.LUGAR = L.ID_LUGAR) + WHERE L.ID_LUGAR = IDLUGAR + GROUP BY (L.ID_LUGAR, L.NOMBRE); + +BEGIN + + OPEN L_PC; + FETCH L_PC INTO V_ID_PAIS, V_NOMBRE, V_CONTADOR; + + WHILE L_PC%FOUND + LOOP + V_SUMA := V_SUMA + V_CONTADOR; + FETCH L_PC INTO V_ID_PAIS, V_NOMBRE, V_CONTADOR; + END LOOP; + CLOSE L_PC; + + OPEN L_C; + FETCH L_C INTO V_ID_PAIS, V_NOMBRE, V_CONTADOR; + + WHILE L_C%FOUND + LOOP + V_SUMA := V_SUMA + V_CONTADOR; + FETCH L_C INTO V_ID_PAIS, V_NOMBRE, V_CONTADOR; + END LOOP; + CLOSE L_C; + SUMA := V_SUMA; +END; + + +-- Ordena los lugares en base a las condiciones dadas +CREATE OR REPLACE PROCEDURE ORDENACION_LUGAR + IS + SUMA INTEGER; + IDL LUGAR.ID_LUGAR%TYPE; + NOMBREL LUGAR.NOMBRE%TYPE; + CURSOR lugares IS + SELECT L.ID_LUGAR, L.NOMBRE + FROM LUGAR L; +BEGIN + OPEN lugares; + FETCH lugares INTO IDL, NOMBREL; + WHILE lugares%FOUND LOOP + SUMA :=0; + OBTENER_CONTADOR(IDL, SUMA); + IF SUMA >= 10 THEN + DBMS_OUTPUT.put_line('El lugar ' || NOMBREL || ' Es de Clasificacion "LUGAR PRINCIPAL" con una cantidad de: ' || SUMA); + ELSIF SUMA >= 5 and SUMA < 9 THEN + DBMS_OUTPUT.put_line('El lugar ' || NOMBREL || ' Es de Clasificacion "LUGAR PRIMARIO" con una cantidad de: ' || SUMA); + ELSIF SUMA < 5 THEN + DBMS_OUTPUT.put_line('El lugar ' || NOMBREL || ' Es de Clasificacion "LUGAR SECUNDARIO" con una cantidad de: ' || SUMA); + END IF; + FETCH lugares INTO IDL, NOMBREL; + END LOOP; +END; +/ + +-- 3 +-- Crear el rol de administrador y asignar permiso para hacer todo con las tablas +CREATE ROLE OLIMPICOS_ADMIN; +GRANT CREATE SESSION TO OLIMPICOS_ADMIN; +GRANT ALL ON ATLETA TO OLIMPICOS_ADMIN; +GRANT ALL ON CAPITAL TO OLIMPICOS_ADMIN; +GRANT ALL ON CATEGORIA TO OLIMPICOS_ADMIN; +GRANT ALL ON CIUDAD TO OLIMPICOS_ADMIN; +GRANT ALL ON COMPETENCIA TO OLIMPICOS_ADMIN; +GRANT ALL ON COMPETER_POR TO OLIMPICOS_ADMIN; +GRANT ALL ON DELEGACION TO OLIMPICOS_ADMIN; +GRANT ALL ON GANAR TO OLIMPICOS_ADMIN; +GRANT ALL ON HOSPEDAR TO OLIMPICOS_ADMIN; +GRANT ALL ON HOTEL TO OLIMPICOS_ADMIN; +GRANT ALL ON LUGAR TO OLIMPICOS_ADMIN; +GRANT ALL ON MEDALLA TO OLIMPICOS_ADMIN; +GRANT ALL ON PAIS TO OLIMPICOS_ADMIN; +GRANT ALL ON PARTICIPAR_COMPETENCIA TO OLIMPICOS_ADMIN; +GRANT ALL ON PARTICIPAR_PRECOMPETENCIA TO OLIMPICOS_ADMIN; +GRANT ALL ON PERTENECER TO OLIMPICOS_ADMIN; +GRANT ALL ON PRECOMPETENCIA TO OLIMPICOS_ADMIN; +GRANT ALL ON TIPOS_DEPORTES TO OLIMPICOS_ADMIN; + +-- Crear el rol de lector y asignar permiso para leer desde todas las tablas +CREATE ROLE OLIMPICOS_LECTOR; +GRANT CREATE SESSION TO OLIMPICOS_LECTOR; +GRANT SELECT ON ATLETA TO OLIMPICOS_LECTOR; +GRANT SELECT ON CAPITAL TO OLIMPICOS_LECTOR; +GRANT SELECT ON CATEGORIA TO OLIMPICOS_LECTOR; +GRANT SELECT ON CIUDAD TO OLIMPICOS_LECTOR; +GRANT SELECT ON COMPETENCIA TO OLIMPICOS_LECTOR; +GRANT SELECT ON COMPETER_POR TO OLIMPICOS_LECTOR; +GRANT SELECT ON DELEGACION TO OLIMPICOS_LECTOR; +GRANT SELECT ON GANAR TO OLIMPICOS_LECTOR; +GRANT SELECT ON HOSPEDAR TO OLIMPICOS_LECTOR; +GRANT SELECT ON HOTEL TO OLIMPICOS_LECTOR; +GRANT SELECT ON LUGAR TO OLIMPICOS_LECTOR; +GRANT SELECT ON MEDALLA TO OLIMPICOS_LECTOR; +GRANT SELECT ON PAIS TO OLIMPICOS_LECTOR; +GRANT SELECT ON PARTICIPAR_COMPETENCIA TO OLIMPICOS_LECTOR; +GRANT SELECT ON PARTICIPAR_PRECOMPETENCIA TO OLIMPICOS_LECTOR; +GRANT SELECT ON PERTENECER TO OLIMPICOS_LECTOR; +GRANT SELECT ON PRECOMPETENCIA TO OLIMPICOS_LECTOR; +GRANT SELECT ON TIPOS_DEPORTES TO OLIMPICOS_LECTOR; + +-- Crear un usuario admin y lector con claves +CREATE USER ADMIN IDENTIFIED BY "adminpass"; +CREATE USER LECTOR IDENTIFIED BY "lectorpass"; + +-- Asignar el usuario admin a rol de admin y usuario lector a rol de lector +GRANT OLIMPICOS_ADMIN TO ADMIN; +GRANT OLIMPICOS_LECTOR TO LECTOR; + +-- 4 +-- La consulta original +SELECT P.ID_PAIS, P.NOMBRE, COUNT(*) AS CANTIDAD_ATLETA +FROM COMPETENCIA C +LEFT JOIN PARTICIPAR_COMPETENCIA PC ON (C.ID_COMPETENCIA = PC.ID_COMPETENCIA) +LEFT JOIN ATLETA A ON A.ID_ATLETA = PC.ID_ATLETA +INNER JOIN DELEGACION D ON (D.ATLETA = A.ID_ATLETA) +INNER JOIN PAIS P ON (P.ID_PAIS = D.PAIS) +WHERE TIPO = (SELECT TD.ID_TIPO FROM TIPOS_DEPORTES TD WHERE (UPPER(TD.DESCRIPCION) = 'ATLETISMO')) +GROUP BY (P.ID_PAIS, P.NOMBRE); + +-- La consulta optimizada +SELECT P.ID_PAIS, P.NOMBRE, COUNT(A.ID_ATLETA) AS CANTIDAD_ATLETA +FROM COMPETENCIA C +LEFT JOIN PARTICIPAR_COMPETENCIA PC ON (C.ID_COMPETENCIA = PC.ID_COMPETENCIA) +LEFT JOIN ATLETA A ON A.ID_ATLETA = PC.ID_ATLETA +INNER JOIN DELEGACION D ON (D.ATLETA = A.ID_ATLETA) +INNER JOIN PAIS P ON (P.ID_PAIS = D.PAIS) +INNER JOIN TIPOS_DEPORTES TD ON (C.TIPO = TD.ID_TIPO AND (UPPER(TD.DESCRIPCION) = 'ATLETISMO')) +GROUP BY (P.ID_PAIS, P.NOMBRE);