Diferència entre revisions de la pàgina «M2 - Bases de dades / Exercicis UF3: Llenguatges SQL / Solucions PL-SQL T6»

De wikiserver
Dreceres ràpides: navegació, cerca
(T6- Creació d'estructures de control)
(T6- Solución 6: Trabajar con Tipos de Dato Compuestos)
 
(Hi ha 14 revisions intermèdies del mateix usuari que no es mostren)
Línia 1: Línia 1:
==T6- Creació d'estructures de control ==
+
==T6- Solución 6: Trabajar con Tipos de Dato Compuestos ==
  
 +
1) Escriba un bloque PL/SQL para imprimir información sobre un país determinado.
  
*'''Exercici 1'''
+
:a) Declare una variable v_countryid. Asigne CA a v_countryid.
 
+
<pre>
Crear una nova taula anomenada MESSAGES per emmagatzemar en una columna anomenada RESULTS cadenes de caràcters de longitud màxima 60 caràcters.
+
  SET SERVEROUTPUT ON
 
+
 +
  SET VERIFY OFF
 +
  DECLARE
 +
    v_countryid varchar2(20):= 'CA';
 +
</pre>
 +
:b) En la sección de declaraciones, utilice el atributo %ROWTYPE y declare la variable v_country_record del tipo countries.
 
<pre>
 
<pre>
CREATE TABLE messages(results VARCHAR2 (60));
+
  v_country_record countries%ROWTYPE;
 
</pre>
 
</pre>
a) crea un bloc per insertar els números del 1 al 10 excepte el 6 i el 8.
+
:c) En la sección ejecutable, obtenga toda la información de la tabla countries mediante v_countryid. Muestre la información seleccionada sobre el país. La salida de ejemplo es la siguiente:
 +
<pre>
 +
  BEGIN
 +
    SELECT *
 +
    INTO v_country_record
 +
    FROM countries
 +
    WHERE country_id = UPPER(v_countryid);
  
b) fes un COMMIT al final del bloc.
+
    DBMS_OUTPUT.PUT_LINE ('Country Id: ' || v_country_record.country_id ||
 +
                          ' Country Name: ' || v_country_record.country_name ||
 +
                          ' Region: ' || v_country_record.region_id);
 +
END;
 +
</pre>
 +
[[Imatge:M2UF3_TDC_1.png |300px|center| Trabajar con Tipos de Dato Compuestos]]
  
c) comprova que la taula messages s'actualitzat correctament.
+
:d) Puede que desee ejecutar y probar el bloque PL/SQL para los países con los identificadores DE, UK y US.
  
::BEGIN
+
<source lang="SQL">
 +
Solució:
  
:::FOR i IN 1..10 LOOP
+
SET SERVEROUTPUT ON
 +
 +
SET VERIFY OFF
 +
DECLARE
 +
  v_country_record countries%ROWTYPE;
 +
  v_countryid varchar2(20):= 'CA';
 +
BEGIN
 +
  SELECT *
 +
  INTO v_country_record
 +
  FROM countries
 +
  WHERE country_id = UPPER(v_countryid);
  
::::IF i = 6 or i = 8 THEN
+
  DBMS_OUTPUT.PUT_LINE ('Country Id: ' || v_country_record.country_id ||
 +
                        ' Country Name: ' || v_country_record.country_name ||
 +
                        ' Region: ' || v_country_record.region_id);
 +
END;
 +
</source>
  
:::::null;
 
  
::::ELSE
 
  
:::::INSERT INTO messages(TO_CHAR(results))
+
2) Cree un bloque PL/SQL para recuperar los nombres de algunos departamentos de la tabla departments e imprimir el nombre de cada departamento en la pantalla, incorporando una matriz asociativa. Guarde el script como lab_06_02_soln.sql.
  
:::::VALUES (i);
+
:a) Declare una tabla INDEX BY dept_table_type del tipo departments.department_name. Declare una variable my_dept_table del tipo dept_table_type para almacenar temporalmente los nombres de los departamentos.
 +
<pre>
 +
  SET SERVEROUTPUT ON
 +
  DECLARE
 +
    TYPE dept_table_type is table of
 +
        departments.department_name%TYPE
 +
        INDEX BY PLS_INTEGER;
 +
    my_dept_table dept_table_type;
 +
</pre>
 +
:b) Declare dos variables: f_loop_count y v_deptno del tipo NUMBER. Asigne 10 a f_loop_count y 0 a v_deptno.
 +
<pre>
 +
  f_loop_count NUMBER (2):=10;
 +
  v_deptno NUMBER (4):=0;
 +
</pre>
 +
:c) Con un bucle, recupere los nombres de 10 departamentos y almacene los nombres en la matriz asociativa. Empiece por department_id 10. Aumente v_deptno en 10 para cada iteración del bucle. La siguiente tabla muestra department_id para los que se debe recuperar department_name y almacenar en la matriz asociativa.
  
::::END IF;
+
[[Imatge:M2UF3_TDC_2.png |500px|center| Trabajar con Tipos de Dato Compuestos]]
  
::::COMMIT;
+
<pre>
 +
  BEGIN
 +
    FOR i IN 1..f_loop_count
 +
    LOOP
 +
      v_deptno:=v_deptno+10;
 +
      SELECT department_name
 +
      INTO my_dept_table(i)
 +
      FROM departments
 +
      WHERE department_id = v_deptno;
 +
    END LOOP;
 +
</pre>
 +
:d) Si utiliza otro bucle, puede recuperar los nombres de los departamentos de la matriz asociativa y mostrarlos.
 +
<pre>
 +
  FOR i IN 1..f_loop_count
 +
    LOOP
 +
      DBMS_OUTPUT.PUT_LINE (my_dept_table(i));
 +
    END LOOP;
 +
  END;
 +
</pre>
 +
:e) Ejecute y guarde el script como lab_06_02_soln.sql. La salida es la siguiente:
  
:::END LOOP;
+
[[Imatge:M2UF3_TDC_3.png |250px|center| Trabajar con Tipos de Dato Compuestos]]
  
::END;
+
<source lang="SQL">
 +
Solució:
  
::/
+
SET SERVEROUTPUT ON
 +
 +
SET VERIFY OFF
 +
DECLARE
 +
  TYPE dept_table_type is table of
 +
      departments.department_name%TYPE
 +
      INDEX BY PLS_INTEGER;
 +
  my_dept_table dept_table_type;
 +
  f_loop_count NUMBER (2):=10;
 +
  v_deptno NUMBER (4):=0;
  
 +
BEGIN
 +
  FOR i IN 1..f_loop_count
 +
  LOOP
 +
    v_deptno:=v_deptno+10;
 +
    SELECT department_name
 +
    INTO my_dept_table(i)
 +
    FROM departments
 +
    WHERE department_id = v_deptno;
 +
  END LOOP;
  
::SELECT *
+
  FOR i IN 1..f_loop_count
 +
  LOOP
 +
    DBMS_OUTPUT.PUT_LINE (my_dept_table(i));
 +
  END LOOP;
 +
END;
 +
</source>
  
::FROM messages;
+
3) Modifique el bloque creado en la Práctica 2 para recuperar toda la información acerca de cada departamento de la tabla departments y mostrarla. Utilice una matriz asociativa con el método de tabla de registros INDEX BY.
  
 +
:a) Cargue el script lab_06_02_soln.sql.
  
*'''Exercici 2'''
+
:b) Ha declarado que la matriz asociativa sea del tipo departments.department_name. Modifique la declaración de la matriz
 
+
asociativa para almacenar temporalmente el número, el nombre y la ubicación de todos los departamentos. Utilice el atributo %ROWTYPE.
Crear un nou bloc plsql per a calcular l'import de la comissió d'un empleat, aquesta comissió dependrà del sou de l'empleat.
+
<pre>
 
+
  SET SERVEROUTPUT ON
a) Inserta un nou empleat en la taula EMP que tingui un sou NULL.
 
 
 
b) Crea una variable per tal d'emmagatzemar el número de l'empleat introduït per teclat.
 
 
 
c) si el sou d'aquest empleat és inferior a 1000$ l'import de la comissió serà un 10% d'aquest sou.
 
 
 
d) si el sou d'aquest empleat està entre 1000$ i 1500$ l'import de la comissió serà un 15% d'aquest sou.
 
 
 
e) si el sou d'aquest empleat és superior a 1500$ l'import de la comissió serà un 20% d'aquest sou.
 
 
 
f) si el sou d'aquest empleat és NULL la comissió serà un 0.
 
 
 
g) comprova el funcionament d'aquest bloc per cadadascun dels casos anteriors.
 
 
 
::ACCEPT p_empno PROMPT 'Introdueix el codi del empleat: '
 
 
 
::DECLARE
 
 
 
:::v_empno emp.empno%TYPE := &p_empno;
 
 
 
:::v_sal emp.sal%TYPE;
 
 
 
:::v_comm emp.comm%TYPE;
 
 
 
::BEGIN
 
 
 
:::SELECT sal INTO v_sal
 
 
 
:::FROM emp
 
 
 
:::WHERE empno = v_empno;
 
 
 
:::IF v_sal < 1000 THEN
 
 
 
::::v_comm := 0.10;
 
 
 
:::ELSIF v_sal BETWEEN 1000 and 1500 THEN
 
 
 
::::v_comm := 0.15;
 
 
 
:::ELSIF v_sal > 1500 THEN
 
 
 
::::v_comm := 0.20;
 
 
 
:::ELSE
 
 
 
::::v_comm := 0;
 
 
 
:::END IF;
 
 
 
:::UPDATE emp
 
 
 
:::SET comm = sal * v_comm
 
 
 
:::WHERE empno = v_empno;
 
 
 
:::COMMIT;
 
 
 
::END;
 
 
 
::/
 
 
 
*'''Exercici 3'''
 
 
 
Modifica l'exercici 1 per afegir al costat del número parell o imparell en funció de si aquest és parell o imparell.
 
 
 
::DECLARE
 
 
 
:::v_num VARCHAR2(10);
 
 
 
::BEGIN
 
 
 
:::FOR i IN 1..10 LOOP
 
 
 
::::IF i = 6 or i = 8 THEN
 
 
 
:::::null;
 
 
 
::::ELSE
 
 
 
:::::IF mod(i,2) = 0 THEN
 
 
 
::::::v_num := i || ' parell';
 
 
 
:::::ELSE
 
 
 
::::::v_num := i || ' imparell';
 
 
 
:::::END IF;
 
 
 
:::::INSERT INTO messages(results)
 
 
 
:::::VALUES (v_num);
 
 
 
::::END IF;
 
 
 
::::COMMIT;
 
 
 
:::END LOOP;
 
 
 
::END;
 
 
 
::/
 
 
 
*'''Exercici 4'''
 
 
 
Afegiu una nova columna a la taula EMP per afegirs asteriscs “*”
 
  
 +
  DECLARE
 +
    TYPE dept_table_type is table of departments%ROWTYPE
 +
      INDEX BY PLS_INTEGER;
 +
    my_dept_table dept_table_type;
 +
    f_loop_count NUMBER (2):=10;
 +
    v_deptno NUMBER (4):=0;
 +
</pre>
 +
:c) Modifique la sentencia SELECT para recuperar toda la información del departamento que está en la tabla departments y almacenarla en la matriz asociativa.
 +
<pre>
 +
BEGIN
 +
  FOR i IN 1..f_loop_count
 +
  LOOP
 +
    v_deptno := v_deptno + 10;
 +
    SELECT *
 +
    INTO my_dept_table(i)
 +
    FROM departments
 +
    WHERE department_id = v_deptno;
 +
  END LOOP;
 +
</pre>
 +
d) Si utiliza otro bucle, puede recuperar la información de los departamentos de la matriz asociativa y mostrarla.
 
<pre>
 
<pre>
ALTER TABLE emp
+
  FOR i IN 1..f_loop_count
ADD stars VARCHAR2 (100);
+
    LOOP
 +
      DBMS_OUTPUT.PUT_LINE ('Department Number: ' || my_dept_table(i).department_id || ' Department Name: ' ||
 +
                            my_dept_table(i).department_name || ' Manager Id: '|| my_dept_table(i).manager_id ||
 +
                            ' Location Id: ' || my_dept_table(i).location_id);
 +
    END LOOP;
 +
  END;
 
</pre>
 
</pre>
 +
La salida de ejemplo es la siguiente:
  
*'''Exercici 5'''
+
[[Imatge:M2UF3_TDC_4.png |550px|center| Trabajar con Tipos de Dato Compuestos]]
 
 
Crea un bloc PL/SQL que introdueixi en la columna creada anteriorment un asterisc per cada 100$ d'un empleat seleccionat per teclat al introduir el seu número d'empleat. Arrodoniu el sou fins el número enter més proper.
 
 
 
::SET VERIFY OFF
 
 
 
::ACCEPT p_empno PROMPT 'Introdueix el codi del empleat: '
 
 
 
::DECLARE
 
 
 
:::v_empno emp.empno%TYPE := &p_empno;
 
 
 
:::v_asterisk emp.stars%TYPE := NULL;
 
 
 
:::v_sal emp.sal%TYPE;
 
 
 
::BEGIN
 
 
 
:::SELECT NVL(ROUND(sal/100), 0) INTO v_sal
 
 
 
:::FROM emp
 
 
 
:::WHERE empno = v_empno;
 
 
 
:::FOR i IN 1 v_sal LOOP
 
 
 
::::v_asterisk := v_asterisk || '*';
 
 
 
:::END LOOP;
 
 
 
:::UPDATE emp
 
 
 
:::SET stars = v_asterisk
 
 
 
:::WHERE empno = v_empno;
 
 
 
:::COMMIT;
 
 
 
::END;
 
 
 
::/
 
  
::SET VERIFY ON
+
<source lang="SQL">
 +
Solució:
  
 +
SET SERVEROUTPUT ON
 +
 +
SET VERIFY OFF
 +
DECLARE
 +
  TYPE dept_table_type is table of departments%ROWTYPE
 +
      INDEX BY PLS_INTEGER;
 +
  my_dept_table dept_table_type;
 +
  f_loop_count NUMBER (2):=10;
 +
  v_deptno NUMBER (4):=0;
  
::SELECT empno, sal, stars
+
BEGIN
 +
  FOR i IN 1..f_loop_count
 +
  LOOP
 +
    v_deptno:=v_deptno+10;
 +
    SELECT *
 +
    INTO my_dept_table(i)
 +
    FROM departments
 +
    WHERE department_id = v_deptno;
 +
  END LOOP;
  
::FROM emp;
+
  FOR i IN 1..f_loop_count
 +
  LOOP
 +
    DBMS_OUTPUT.PUT_LINE ('Department Number: ' || my_dept_table(i).department_id || ' Department Name: ' ||
 +
                          my_dept_table(i).department_name || ' Manager Id: '|| my_dept_table(i).manager_id ||
 +
                          ' Location Id: ' || my_dept_table(i).location_id);
 +
  END LOOP;
 +
END;
 +
</source>

Revisió de 21:19, 1 març 2021

T6- Solución 6: Trabajar con Tipos de Dato Compuestos

1) Escriba un bloque PL/SQL para imprimir información sobre un país determinado.

a) Declare una variable v_countryid. Asigne CA a v_countryid.
  SET SERVEROUTPUT ON
 
  SET VERIFY OFF
  DECLARE
    v_countryid varchar2(20):= 'CA';
b) En la sección de declaraciones, utilice el atributo %ROWTYPE y declare la variable v_country_record del tipo countries.
  v_country_record countries%ROWTYPE;
c) En la sección ejecutable, obtenga toda la información de la tabla countries mediante v_countryid. Muestre la información seleccionada sobre el país. La salida de ejemplo es la siguiente:
  BEGIN
    SELECT *
    INTO v_country_record
    FROM countries
    WHERE country_id = UPPER(v_countryid);

    DBMS_OUTPUT.PUT_LINE ('Country Id: ' || v_country_record.country_id ||
                          ' Country Name: ' || v_country_record.country_name ||
                          ' Region: ' || v_country_record.region_id);
END;
Trabajar con Tipos de Dato Compuestos
d) Puede que desee ejecutar y probar el bloque PL/SQL para los países con los identificadores DE, UK y US.
Solució:

SET SERVEROUTPUT ON
 
SET VERIFY OFF
DECLARE
  v_country_record countries%ROWTYPE;
  v_countryid varchar2(20):= 'CA';
BEGIN
  SELECT *
  INTO v_country_record
  FROM countries
  WHERE country_id = UPPER(v_countryid);

  DBMS_OUTPUT.PUT_LINE ('Country Id: ' || v_country_record.country_id ||
                        ' Country Name: ' || v_country_record.country_name ||
                        ' Region: ' || v_country_record.region_id);
END;


2) Cree un bloque PL/SQL para recuperar los nombres de algunos departamentos de la tabla departments e imprimir el nombre de cada departamento en la pantalla, incorporando una matriz asociativa. Guarde el script como lab_06_02_soln.sql.

a) Declare una tabla INDEX BY dept_table_type del tipo departments.department_name. Declare una variable my_dept_table del tipo dept_table_type para almacenar temporalmente los nombres de los departamentos.
  SET SERVEROUTPUT ON
  DECLARE
    TYPE dept_table_type is table of
         departments.department_name%TYPE
         INDEX BY PLS_INTEGER;
    my_dept_table dept_table_type;
b) Declare dos variables: f_loop_count y v_deptno del tipo NUMBER. Asigne 10 a f_loop_count y 0 a v_deptno.
  f_loop_count NUMBER (2):=10;
  v_deptno NUMBER (4):=0;
c) Con un bucle, recupere los nombres de 10 departamentos y almacene los nombres en la matriz asociativa. Empiece por department_id 10. Aumente v_deptno en 10 para cada iteración del bucle. La siguiente tabla muestra department_id para los que se debe recuperar department_name y almacenar en la matriz asociativa.
Trabajar con Tipos de Dato Compuestos
  BEGIN
    FOR i IN 1..f_loop_count
    LOOP
      v_deptno:=v_deptno+10;
      SELECT department_name
      INTO my_dept_table(i)
      FROM departments
      WHERE department_id = v_deptno;
    END LOOP;
d) Si utiliza otro bucle, puede recuperar los nombres de los departamentos de la matriz asociativa y mostrarlos.
  FOR i IN 1..f_loop_count
    LOOP
      DBMS_OUTPUT.PUT_LINE (my_dept_table(i));
    END LOOP;
  END;
e) Ejecute y guarde el script como lab_06_02_soln.sql. La salida es la siguiente:
Trabajar con Tipos de Dato Compuestos
Solució:

SET SERVEROUTPUT ON
 
SET VERIFY OFF
DECLARE
  TYPE dept_table_type is table of
       departments.department_name%TYPE
       INDEX BY PLS_INTEGER;
  my_dept_table dept_table_type;
  f_loop_count NUMBER (2):=10;
  v_deptno NUMBER (4):=0;

BEGIN
  FOR i IN 1..f_loop_count
  LOOP
    v_deptno:=v_deptno+10;
    SELECT department_name
    INTO my_dept_table(i)
    FROM departments
    WHERE department_id = v_deptno;
  END LOOP;

  FOR i IN 1..f_loop_count
  LOOP
    DBMS_OUTPUT.PUT_LINE (my_dept_table(i));
  END LOOP;
END;

3) Modifique el bloque creado en la Práctica 2 para recuperar toda la información acerca de cada departamento de la tabla departments y mostrarla. Utilice una matriz asociativa con el método de tabla de registros INDEX BY.

a) Cargue el script lab_06_02_soln.sql.
b) Ha declarado que la matriz asociativa sea del tipo departments.department_name. Modifique la declaración de la matriz

asociativa para almacenar temporalmente el número, el nombre y la ubicación de todos los departamentos. Utilice el atributo %ROWTYPE.

  SET SERVEROUTPUT ON

  DECLARE
    TYPE dept_table_type is table of departments%ROWTYPE
      INDEX BY PLS_INTEGER;
    my_dept_table dept_table_type;
    f_loop_count NUMBER (2):=10;
    v_deptno NUMBER (4):=0;
c) Modifique la sentencia SELECT para recuperar toda la información del departamento que está en la tabla departments y almacenarla en la matriz asociativa.
BEGIN
  FOR i IN 1..f_loop_count
  LOOP
    v_deptno := v_deptno + 10;
    SELECT *
    INTO my_dept_table(i)
    FROM departments
    WHERE department_id = v_deptno;
  END LOOP;

d) Si utiliza otro bucle, puede recuperar la información de los departamentos de la matriz asociativa y mostrarla.

  FOR i IN 1..f_loop_count
    LOOP
      DBMS_OUTPUT.PUT_LINE ('Department Number: ' || my_dept_table(i).department_id || ' Department Name: ' ||
                            my_dept_table(i).department_name || ' Manager Id: '|| my_dept_table(i).manager_id || 
                            ' Location Id: ' || my_dept_table(i).location_id);
    END LOOP;
  END;

La salida de ejemplo es la siguiente:

Trabajar con Tipos de Dato Compuestos
Solució:

SET SERVEROUTPUT ON
 
SET VERIFY OFF
DECLARE
  TYPE dept_table_type is table of departments%ROWTYPE
       INDEX BY PLS_INTEGER;
  my_dept_table dept_table_type;
  f_loop_count NUMBER (2):=10;
  v_deptno NUMBER (4):=0;

BEGIN
  FOR i IN 1..f_loop_count
  LOOP
    v_deptno:=v_deptno+10;
    SELECT *
    INTO my_dept_table(i)
    FROM departments
    WHERE department_id = v_deptno;
  END LOOP;

  FOR i IN 1..f_loop_count
  LOOP
    DBMS_OUTPUT.PUT_LINE ('Department Number: ' || my_dept_table(i).department_id || ' Department Name: ' ||
                          my_dept_table(i).department_name || ' Manager Id: '|| my_dept_table(i).manager_id || 
                          ' Location Id: ' || my_dept_table(i).location_id);
  END LOOP;
END;