geofox

Mi guia PL/SQL

Mar 18th, 2012
565
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PL/SQL 31.42 KB | None | 0 0
  1. 1. Comprobacion de estado de  serveroutput
  2.  
  3. SHOW SERVEROUTPUT;
  4.  
  5. Estado  :
  6.  
  7. SERVEROUTPUT OFF
  8.  
  9. 2. Escribir un bloque anónimo PL/SQL que muestre por pantalla el nombre de usuario de sesión en Oracle (usar la pseudoconstante USER).
  10.  
  11. BEGIN
  12.      
  13.         DBMS_OUTPUT.PUT_LINE(' USUARIO DE SESIÓN : ' || USER);
  14. END;
  15. /
  16.  
  17. 3. Activar SERVEROUTPUT e incluir esta activación en el archivo login.SQL
  18.  
  19. SET SERVEROUTPUT ON;
  20. @login.SQL;
  21.  
  22. 4. Compruebe lo que ocurre ejecutando de nuevo el bloque de código del Ejercicio 2
  23.  
  24. Se mostro la salida del bloque PL/SQL:
  25. USUARIO DE SESIÓN : OWN_GUIA5
  26.  
  27. El estado de SERVEROUTPUT  será  ON  en todas las sesiones de usuario en oracle
  28.  
  29. 5. Escribe un bloque PL/SQL donde DECLARE una variable, inicializada a la fecha actual,  que imprime su valor en pantalla
  30.  
  31. DECLARE
  32. FECHA DATE:=SYSDATE;
  33. BEGIN
  34.         DBMS_OUTPUT.PUT_LINE(' FECHA ACTUAL :  ' || TO_CHAR(FECHA));
  35. END;
  36. /
  37.  
  38. 6. Escribe un bloque PL/SQL que almacene en una variable numérica el año actual. Muestra  en pantalla el año. Puede usar las funciones TO_NUMBER() y TO_CHAR().
  39.  
  40. DECLARE
  41. YEAR NUMBER;
  42. BEGIN
  43.         SELECT TO_CHAR(SYSDATE, 'YYYY') INTO YEAR FROM DUAL;
  44.         DBMS_OUTPUT.PUT_LINE(' AÑO ACTUAL : ' || YEAR);
  45. END;
  46. /
  47.  
  48. 7. Cree una tabla PRODUCTO(CODPROD, NOMPROD, PRECIO), usando SQL (no usar un bloque PL/SQL)
  49.  
  50. CREATE TABLE PRODUCTO(
  51. CODPROD INTEGER CONSTRAINT PK_CODIGO_PROD PRIMARY KEY,
  52. NOMPROD VARCHAR2(100) NOT NULL,
  53. PRECIO NUMBER (8,2) NOT NULL );
  54.  
  55.  
  56. 8. Añadir un producto a la tabla usando una sentencia INSERT dentro de un bloque PL/SQL
  57.  
  58. BEGIN
  59.       INSERT INTO PRODUCTO VALUES(1,'LAPTOP TOSHIBA 1520',500);
  60.  
  61. END;
  62. /
  63.  
  64. 9. Añadir otro producto, ahora utilizando una lista de variables en la sentencia INSERT.
  65.  
  66. DECLARE
  67. CODIGO INTEGER:=2;
  68. PRODUCTO VARCHAR2(100):='DISCO DURO EXTERNO WESTERN 1TB';
  69. PRECIO NUMBER(8,2):=100;
  70. BEGIN
  71.     INSERT INTO PRODUCTO VALUES(CODIGO,PRODUCTO,PRECIO);
  72.    
  73.  
  74. END;
  75. /
  76.  
  77. 10. Añadir, ahora usando un registro PL/SQL, dos productos mas.
  78.  
  79. DECLARE
  80. REGISTRO PRODUCTO%ROWTYPE;
  81.  BEGIN
  82.                REGISTRO.CODPROD:=3;
  83.                REGISTRO.NOMPROD:= 'ANTIVIRUS BITDEFENDER TOTAL SECURITY 2012';
  84.                REGISTRO.PRECIO :=80;
  85.                
  86.               INSERT INTO PRODUCTO VALUES REGISTRO;
  87.                                    
  88.                REGISTRO.CODPROD:=4;
  89.                REGISTRO.NOMPROD:= 'MICROSOFT  WINDOWS 7 PROFESIONAL';
  90.                REGISTRO.PRECIO :=175;
  91.    
  92.               INSERT INTO PRODUCTO VALUES REGISTRO;
  93.    
  94. END;
  95. /
  96.  
  97. 11. Borrar el primer producto insertado, e incrementar el precio de los demás en un 5%
  98.  
  99. DECLARE
  100. PORCENTAJE NUMBER(8,2);
  101. PRECIO_INCREMENTO NUMBER(8,2);
  102. CODIGO INTEGER;
  103. NUM_PRODUCTO INTEGER:=1; -- PRIMER PRODUCTO INSERTADO Ó FILA
  104. CURSOR C_REGISTROS  IS SELECT ROWNUM,CODPROD,PRECIO FROM PRODUCTO;
  105.  BEGIN
  106.  
  107.       FOR i IN  C_REGISTROS  LOOP
  108.      
  109.       IF i.ROWNUM=NUM_PRODUCTO THEN
  110.      
  111.              /* OBTENIENDO CODPROD PRIMER PRODUCTO INSERTADO */
  112.               SELECT CODPROD INTO CODIGO FROM PRODUCTO WHERE ROWNUM=NUM_PRODUCTO;
  113.            
  114.               DELETE FROM PRODUCTO WHERE CODPROD=CODIGO;
  115.       END IF;
  116.      
  117.        PORCENTAJE := (i.PRECIO *  0.05);
  118.        PRECIO_INCREMENTO:= (i.PRECIO +  PORCENTAJE);
  119.      
  120.        UPDATE PRODUCTO SET PRECIO =  PRECIO_INCREMENTO WHERE CODPROD=i.CODPROD;
  121.                
  122.        END LOOP;
  123.   END;
  124. /      
  125.  
  126. 12.   Obtener y mostrar en pantalla el número de productos que hay almacenados, usando SELECT ... INTO y el mensaje “Hay n productos”.  
  127.  
  128. DECLARE
  129. NUMERO_PRODUCTOS INTEGER;
  130. BEGIN
  131.         SELECT COUNT(*) INTO  NUMERO_PRODUCTOS FROM  PRODUCTO;
  132.         DBMS_OUTPUT.PUT_LINE(' Hay  ' || TO_CHAR( NUMERO_PRODUCTOS) ||  ' Productos ');
  133.  END;
  134. /
  135.  
  136. 13. Obtener y muestra todos los datos de un producto (buscar a partir de la clave primaria, escogiendo un código de producto existente.
  137. Usar SELECT ... INTO y un registro PL/SQL.
  138.  
  139. DECLARE
  140. REGISTRO PRODUCTO%ROWTYPE;
  141. BEGIN
  142.    
  143.      SELECT CODPROD,NOMPROD,PRECIO INTO REGISTRO FROM PRODUCTO  WHERE CODPROD =3;
  144.      
  145.      DBMS_OUTPUT.PUT_LINE(' CODIGO :' || TO_CHAR(REGISTRO.CODPROD) || ' NOMBRE : ' || TO_CHAR(REGISTRO.NOMPROD)
  146.      || ' PRECIO : '  || TO_CHAR(REGISTRO.PRECIO) );
  147.  
  148. END;
  149. /
  150.  
  151. 14. Modificar el Ejercicio 13 de forma que busque un producto que no exista
  152.  
  153. DECLARE
  154. CODIGO INTEGER:=5;
  155. REGISTRO PRODUCTO%ROWTYPE;
  156. EXISTENCIA INTEGER;
  157. BEGIN
  158.  
  159.        SELECT COUNT(*) INTO EXISTENCIA FROM PRODUCTO WHERE CODPROD=CODIGO;
  160.        
  161.        IF EXISTENCIA = 0 THEN
  162.                    DBMS_OUTPUT.PUT_LINE(' NO EXISTE EL PRODUCTO ' );
  163.                    
  164.         ELSE
  165.                   SELECT CODPROD,NOMPROD,PRECIO INTO REGISTRO FROM PRODUCTO  WHERE CODPROD=CODIGO;
  166.                  DBMS_OUTPUT.PUT_LINE(' CODIGO :' || TO_CHAR(REGISTRO.CODPROD) || ' NOMBRE : ' || TO_CHAR(REGISTRO.NOMPROD)
  167.                  || ' PRECIO : '  || TO_CHAR(REGISTRO.PRECIO) );
  168.         END IF;
  169.  
  170.  END;
  171. /
  172.  
  173. 15 .  Modificar de nuevo el Ejercicio 13, ahora eliminando el WHERE de la consulta, de forma que
  174. existan varios productos.
  175.  
  176. DECLARE
  177. CURSOR C_REGISTROS  IS  SELECT CODPROD,NOMPROD,PRECIO  FROM PRODUCTO;
  178.  
  179.  BEGIN
  180.    
  181.       FOR REGISTRO IN C_REGISTROS  LOOP
  182.            
  183.         DBMS_OUTPUT.PUT_LINE(' CODIGO :' || TO_CHAR(REGISTRO.CODPROD) || ' NOMBRE : ' || TO_CHAR(REGISTRO.NOMPROD)
  184.        || ' PRECIO : '  || TO_CHAR(REGISTRO.PRECIO) );
  185.        
  186.      END LOOP;
  187. END;
  188. /
  189.  
  190. 16. Modificar el Ejercicio 12, que mostraba el número de productos, de forma que indique “No hay productos” en vez de “Hay 0 productos”    
  191.  
  192. DECLARE
  193. NUMERO_PRODUCTOS INTEGER;
  194. BEGIN
  195.        
  196.         SELECT COUNT(*) INTO  NUMERO_PRODUCTOS FROM  PRODUCTO;
  197.          
  198.          IF  NUMERO_PRODUCTOS = 0 THEN
  199.                  DBMS_OUTPUT.PUT_LINE(' No hay Productos ');
  200.         ELSE
  201.                 DBMS_OUTPUT.PUT_LINE(' Hay  ' || TO_CHAR(NUMERO_PRODUCTOS) ||  ' Productos ');
  202.         END IF;    
  203.        
  204. END;
  205. /
  206.  
  207. 17. Modificar de nuevo el bloque PL/SQL anterior, de forma que se indique que no hay produtos, que hay pocos (si hay entre 1 y 3)
  208. o el número exacto de productos existentes (si hay más de 3).
  209.  
  210. DECLARE
  211. NUMERO_PRODUCTOS INTEGER;
  212. BEGIN
  213.        
  214.         SELECT COUNT(*) INTO  NUMERO_PRODUCTOS FROM  PRODUCTO;
  215.          
  216.       IF NUMERO_PRODUCTOS = 0 THEN
  217.                  DBMS_OUTPUT.PUT_LINE(' No hay Productos ');
  218.        
  219.         ELSIF NUMERO_PRODUCTOS > 0 AND NUMERO_PRODUCTOS <=3 THEN
  220.                   DBMS_OUTPUT.PUT_LINE(' Hay Pocos Productos ');
  221.          
  222.         ELSIF NUMERO_PRODUCTOS > 3 THEN
  223.                      DBMS_OUTPUT.PUT_LINE(' Hay  ' || TO_CHAR(NUMERO_PRODUCTOS) ||  ' Productos ');      
  224.            
  225.         END IF;
  226.        
  227. END;
  228. /
  229.  
  230. 18. Usar un bucle simple (LOOP ... END LOOP) para mostrar los números pares entre 1 y 10.
  231.  Pueden usar la función MOD(dividendo,divisor) para averiguar si el número es par o impar
  232.  
  233. DECLARE
  234. CONTADOR_PARES NUMBER:=0;
  235. BEGIN
  236.  
  237.      LOOP
  238.          CONTADOR_PARES:=CONTADOR_PARES +1 ;
  239.     EXIT WHEN CONTADOR_PARES  > 10;
  240.      IF MOD(CONTADOR_PARES,2)=0 THEN
  241.             DBMS_OUTPUT.PUT_LINE(TO_CHAR(CONTADOR_PARES));
  242.            
  243.     END IF;
  244.    END LOOP;
  245.    
  246. END;
  247. /
  248.  
  249. 19. Imprimir de nuevo los números pares entre 1 y 10, pero ahora usando un bucle WHILE
  250.  
  251. DECLARE
  252. CONTADOR_PARES NUMBER:=1;
  253. BEGIN
  254.    
  255.     WHILE (CONTADOR_PARES <=10)
  256.     LOOP
  257.    
  258.          IF MOD(CONTADOR_PARES,2)=0 THEN
  259.              DBMS_OUTPUT.PUT_LINE(TO_CHAR(CONTADOR_PARES));
  260.     END IF;
  261.  
  262.     CONTADOR_PARES:= CONTADOR_PARES +1 ;
  263.    
  264.     END LOOP;
  265.    
  266.  END;
  267. /
  268.  
  269. 20. Imprimir de nuevo los números pares entre 1 y 10, pero ahora usando un bucle FOR
  270.  
  271. BEGIN
  272.  
  273.       FOR  CONTADOR_PARES IN 1..10 LOOP
  274.            
  275.            IF MOD( CONTADOR_PARES,2)=0 THEN
  276.                   DBMS_OUTPUT.PUT_LINE(TO_CHAR(CONTADOR_PARES));
  277.            
  278.           END IF;
  279.    
  280.       END LOOP;
  281. END;
  282. /
  283.  
  284.  
  285. 21. Utilizar un CURSOR y un bucle LOOP simple para recuperar y mostrar los datos de todos Los productos.
  286. Indicar al final cuantos productos hay
  287.  
  288. DECLARE
  289. CURSOR C_REGISTROS IS SELECT * FROM PRODUCTO;
  290. CODIGO INTEGER;
  291. PRODUCTO VARCHAR2(100) ;
  292. PRECIO NUMBER(8,2);
  293. BEGIN
  294.     OPEN C_REGISTROS;
  295.     LOOP
  296.       FETCH C_REGISTROS  INTO CODIGO,PRODUCTO,PRECIO;
  297.       EXIT WHEN C_REGISTROS%NOTFOUND;
  298.         DBMS_OUTPUT.PUT_LINE(' CODIGO :' || TO_CHAR(CODIGO) || ' NOMBRE : ' || TO_CHAR(PRODUCTO) || ' PRECIO : '  || TO_CHAR(PRECIO));
  299.   END LOOP;
  300.   DBMS_OUTPUT.PUT_LINE(' CANTIDAD DE PRODUCTOS : ' || C_REGISTROS %ROWCOUNT);
  301.     CLOSE C_REGISTROS ;
  302.      
  303. END;
  304. /
  305.  
  306. 22. Mostrar los datos de todos los productos, pero ahora usando un bucle WHILE para recorrer el CURSOR, e indicar
  307. también el número de productos encontrado
  308.  
  309. DECLARE
  310. CURSOR  C_REGISTROS IS SELECT * FROM PRODUCTO;
  311. CODIGO INTEGER;
  312. PRODUCTO VARCHAR2(100) ;
  313. PRECIO NUMBER(8,2);
  314. BEGIN
  315.        
  316.     OPEN  C_REGISTROS;
  317.     FETCH  C_REGISTROS INTO CODIGO,PRODUCTO,PRECIO;
  318.     WHILE  C_REGISTROS%FOUND
  319.     LOOP
  320.           DBMS_OUTPUT.PUT_LINE(' CODIGO :' || TO_CHAR(CODIGO) || ' NOMBRE : ' || TO_CHAR(PRODUCTO) || ' PRECIO : '  || TO_CHAR(PRECIO));
  321.              FETCH C_REGISTROS INTO CODIGO,PRODUCTO,PRECIO;
  322.     END LOOP;
  323.      DBMS_OUTPUT.PUT_LINE(' CANTIDAD DE PRODUCTOS : ' ||  C_REGISTROS%ROWCOUNT);
  324.     CLOSE  C_REGISTROS;
  325.    
  326. END;
  327. /
  328.  
  329. 23. Recuperar e imprimir de nuevo los datos de todos los productos, y cuantos hay, pero ahora usa un bucle FOR
  330.  
  331. DECLARE
  332. CONTADOR_PRODUCTOS  INTEGER:=0;
  333. CURSOR C_REGISTROS IS SELECT * FROM PRODUCTO;
  334. BEGIN
  335.  
  336.       FOR  i IN C_REGISTROS LOOP
  337.      
  338.             DBMS_OUTPUT.PUT_LINE(' CODIGO :' || TO_CHAR(i.CODPROD) || ' NOMBRE : ' || TO_CHAR(i.NOMPROD)
  339.            || ' PRECIO : '  || TO_CHAR(i.PRECIO));
  340.            
  341.             CONTADOR_PRODUCTOS:= CONTADOR_PRODUCTOS+1;    
  342.      
  343.       END LOOP;
  344.       DBMS_OUTPUT.PUT_LINE(' CANTIDAD DE PRODUCTOS : ' || TO_CHAR(CONTADOR_PRODUCTOS));
  345.  
  346.    END;
  347. /
  348.  
  349. 24. Modificar el Ejercicio 23, de forma que se utilice la consulta directamente en el bucle FOR en vez de declarar explícitamente el CURSOR.
  350.  
  351. DECLARE
  352. CONTADOR_PRODUCTOS  INTEGER:=0;
  353. BEGIN
  354.       FOR  i IN  (SELECT * FROM PRODUCTO)  LOOP
  355.            
  356.                 DBMS_OUTPUT.PUT_LINE(' CODIGO :' || TO_CHAR(i.CODPROD) || ' NOMBRE : ' || TO_CHAR(i.NOMPROD)
  357.                || ' PRECIO : '  || TO_CHAR(i.PRECIO));
  358.            
  359.                 CONTADOR_PRODUCTOS:= CONTADOR_PRODUCTOS+1;    
  360.       END LOOP;
  361.       DBMS_OUTPUT.PUT_LINE(' CANTIDAD DE PRODUCTOS : ' || TO_CHAR(CONTADOR_PRODUCTOS));
  362.  
  363.  
  364. END;
  365. /
  366.  
  367. 25. Modificar ahora el Ejercicio 24, de forma que se recuperen solo los códigos de los productos.
  368. Ya no es necesario indicar cuantos productos hay.
  369.  
  370. BEGIN
  371.  
  372.       FOR  i IN  (SELECT CODPROD FROM PRODUCTO)  LOOP
  373.            DBMS_OUTPUT.PUT_LINE(' CODIGO : ' || TO_CHAR(i.CODPROD));
  374.            
  375.       END LOOP;
  376.      
  377.      
  378. END;
  379. /
  380.  
  381. 26. Recuperar ahora el doble del precio de los productos, usando el bucle FOR con la consulta directamente
  382.  
  383. BEGIN
  384.  
  385.       FOR  i IN  (SELECT PRECIO * 2 AS DOBLE  FROM PRODUCTO)  LOOP
  386.            DBMS_OUTPUT.PUT_LINE(' PRECIO :' || TO_CHAR(i.DOBLE));
  387.            
  388.       END LOOP;
  389.    
  390. END;
  391. /
  392.  
  393. 27. Escribir un bloque PL/SQL que modifique el producto 3, poniendo Monitor TFT 21'' como nombre del producto, y 497 como precio.
  394. Si no existe el producto con código 3, el bloque PL/SQL escrito debe insertar los valores indicados.
  395. El uso del CURSOR implícito SQL podría ayudar a resolver este ejercicio.
  396.  
  397. DECLARE
  398. CODIGO INTEGER:=3;
  399. NOMBRE VARCHAR2(100):='Monitor TFT 21''';
  400. PRECIO_PRODUCTO NUMBER(8,2):=497;
  401. EXISTENCIA INTEGER;
  402. BEGIN
  403.  
  404.       SELECT  COUNT(*) INTO EXISTENCIA FROM PRODUCTO WHERE CODPROD=CODIGO;
  405.        
  406.         IF EXISTENCIA=0  THEN
  407.                 INSERT INTO PRODUCTO VALUES(CODIGO,NOMBRE,PRECIO_PRODUCTO);
  408.                   DBMS_OUTPUT.PUT_LINE(TO_CHAR(CODIGO) ||'   ' || TO_CHAR(NOMBRE) ||'  ' || '   '  ||TO_CHAR(PRECIO_PRODUCTO) || '  REGISTRO INSERTADO ');
  409.         ELSE
  410.                 UPDATE PRODUCTO SET NOMPROD=NOMBRE,PRECIO=PRECIO_PRODUCTO WHERE CODPROD=CODIGO;
  411.                  DBMS_OUTPUT.PUT_LINE(TO_CHAR(CODIGO) ||'   ' || TO_CHAR(NOMBRE) ||'  ' || '   '  ||TO_CHAR(PRECIO_PRODUCTO) || '  REGISTRO ACTUALIZADO ');
  412.         END IF;
  413.    
  414. END;
  415. /
  416.  
  417. 28. En un bloque PL/SQL, intentar crear directamente una tabla T con un campo numérico C (fallara)
  418.  
  419. BEGIN
  420. CREATE TABLE T(
  421. C NUMBER
  422. );
  423.  
  424. END;
  425. /
  426.  
  427. 29. Crear la tabla usando SQL dinámico y EXECUTE IMMEDIATE dentro de un bloque PL/SQL.
  428. Comprobar que efectivamente la tabla fue creada, con una consulta simple sobre el catálogo de Oracle.
  429. Finalmente, eliminar (DROP) la tabla.
  430.  
  431. DECLARE
  432. TABLA VARCHAR2(100);
  433. BEGIN
  434.  
  435.        EXECUTE IMMEDIATE  'CREATE TABLE T(C NUMBER)';
  436.    
  437.        SELECT TABLE_NAME INTO TABLA  FROM USER_TABLES WHERE TABLE_NAME='T';
  438.        DBMS_OUTPUT.PUT_LINE(' TABLA : ' || TABLA || ' CREADA ' );
  439.      
  440.  
  441.        EXECUTE IMMEDIATE  'DROP TABLE T';
  442.      
  443.        DBMS_OUTPUT.PUT_LINE(' TABLA : ' || TABLA || ' ELIMINADA ' );
  444.  
  445. END;
  446. /
  447.  
  448. 30. De nuevo en un bloque PL/SQL, crear una tabla T2 con un campo S alfanumérico, e insertar una fila en esa tabla.
  449.  
  450. DECLARE
  451. TABLA  VARCHAR2(100);
  452. BEGIN
  453.  
  454.        EXECUTE IMMEDIATE  'CREATE TABLE T2(S VARCHAR2(100))';
  455.  
  456.        SELECT TABLE_NAME INTO TABLA  FROM USER_TABLES WHERE TABLE_NAME='T2';
  457.        DBMS_OUTPUT.PUT_LINE(' TABLA : ' || TABLA || ' CREADA ' );
  458.      
  459.       EXECUTE IMMEDIATE  'INSERT INTO T2 VALUES(''GFX1821'')';
  460.       DBMS_OUTPUT.PUT_LINE( SQL%ROWCOUNT || ' FILA INSERTADA ');
  461.    
  462.  
  463. END;
  464. /
  465.  
  466. 31. Recuperar e imprimir de nuevo los datos de todos los productos, ahora usando SQL dinámico.
  467.  
  468. DECLARE
  469. TYPE C_REFERIDO IS REF CURSOR;
  470. C_REGISTROS C_REFERIDO;
  471. PRODUCTOS  PRODUCTO%ROWTYPE;
  472. CONSULTA_DINAMICA VARCHAR2(254);
  473. BEGIN
  474.  
  475.   CONSULTA_DINAMICA:='SELECT * FROM PRODUCTO';
  476.  
  477.   OPEN C_REGISTROS  FOR CONSULTA_DINAMICA;
  478.   LOOP
  479.      FETCH C_REGISTROS  INTO  PRODUCTOS;
  480.       EXIT WHEN C_REGISTROS%NOTFOUND;
  481.       DBMS_OUTPUT.PUT_LINE(' CODIGO :' || TO_CHAR(PRODUCTOS.CODPROD) || ' NOMBRE : ' || TO_CHAR( PRODUCTOS.NOMPROD)
  482.       || ' PRECIO : '   || TO_CHAR(PRODUCTOS.PRECIO));
  483.  
  484.    END LOOP;
  485.    
  486.              CLOSE C_REGISTROS;
  487. END;
  488. /
  489.  
  490.  
  491. 32. Alterar la tabla de productos, añadiendo una restricción c_precio_positivo que compruebe que el precio de un producto es mayor que cero.
  492.  
  493. ALTER TABLE PRODUCTO
  494. ADD CONSTRAINT c_precio_positivo CHECK(PRECIO > 0);
  495.  
  496.  
  497. 33. Averiguar como podría controlar el error de clave primaria (o restricción única) duplicada.
  498.  
  499. El error se  puede controlar con la excepción:
  500.  
  501.  DUP_VAL_ON_INDEX
  502.  
  503.  
  504.  34. Crear un bloque PL/SQL en el que se inserta un producto con código 3, ya existente. Haz el control de excepciones
  505. de forma que un error de clave primaria duplicada se ignore (no se inserta el producto pero el bloque PL/SQL se ejecuta correctamente).
  506. Si intentamos insertar un producto con precio negativo, debe aparecer un error.
  507.  
  508. DECLARE
  509. CODIGO INTEGER:=3;
  510. PRODUCTO VARCHAR2(100):='MINI LAPTOP ACER 1510';
  511. PRECIO NUMBER(8,2):=350;
  512. BEGIN
  513.    
  514.     IF PRECIO > 0 THEN
  515.           INSERT INTO PRODUCTO VALUES(CODIGO,PRODUCTO,PRECIO);
  516.                  
  517.    ELSE
  518.            DBMS_OUTPUT.PUT_LINE(  ' ERROR : PRECIO  NEGATIVO ');
  519.    
  520.    END IF;
  521.          
  522.       EXCEPTION
  523.           WHEN DUP_VAL_ON_INDEX THEN
  524.           DBMS_OUTPUT.PUT_LINE(  ' CLAVE PRIMARIA DUPLICADA ');
  525.    
  526.    
  527. END;
  528. /
  529.  
  530.  35. Eliminar la restricción c_precio_positivo creada en el Ejercicio 32.
  531.  
  532. ALTER TABLE PRODUCTO
  533. DROP CONSTRAINT  c_precio_positivo;
  534.  
  535.  
  536. 36. Escribe un bloque PL/SQL donde usas un registro para almacenar los datos de un producto.
  537. El bloque insertará ese producto, pero si el precio no es positivo generar ´a una excepción de tipo precio_prod_invalido,
  538. que deberá declarar previamente, en vez de realizar la inserción
  539.  
  540. DECLARE
  541. REGISTROS PRODUCTO%ROWTYPE;
  542. precio_prod_invalido EXCEPTION;
  543. BEGIN
  544.                REGISTROS.CODPROD:=6;
  545.                REGISTROS.NOMPROD:= 'IPAD 3';
  546.                REGISTROS.PRECIO :=1000;
  547.                
  548.                IF  REGISTROS.PRECIO > 0 THEN
  549.                        INSERT INTO PRODUCTO VALUES REGISTROS;
  550.                        
  551.               ELSE
  552.              
  553.                         RAISE precio_prod_invalido;
  554.                        
  555.               END IF;
  556.              
  557.               EXCEPTION
  558.                   WHEN   precio_prod_invalido  THEN
  559.                   DBMS_OUTPUT.PUT_LINE(  ' ERROR : PRECIO NEGATIVO ');        
  560. END;
  561. /
  562.  
  563. 37. Modificar el Ejercicio 36, de forma que capture la excepción elevada
  564.  
  565. DECLARE
  566. REGISTROS PRODUCTO%ROWTYPE;
  567. precio_prod_invalido EXCEPTION;
  568. BEGIN
  569.          
  570.                REGISTROS.CODPROD:=7;
  571.                REGISTROS.NOMPROD:= 'IPHONE 5';
  572.                REGISTROS.PRECIO :=700;
  573.                
  574.                IF   REGISTROS.PRECIO > 0 THEN
  575.                        INSERT INTO PRODUCTO VALUES REGISTROS;
  576.                        
  577.               ELSE
  578.              
  579.                         RAISE precio_prod_invalido;
  580.                        
  581.               END IF;
  582.              
  583.               EXCEPTION
  584.                  WHEN   precio_prod_invalido  THEN
  585.                  RAISE_APPLICATION_ERROR(-20001,' ERROR : PRECIO NEGATIVO ');        
  586. END;
  587. /
  588.  
  589. 38. Modificar de nuevo el Ejercicio 36, de forma que ahora captures la excepción elevada y produces otra,
  590.  con SQLCODE y mensaje de error especifico, usando RAISE_APPLICATION_ERROR
  591.  
  592.  DECLARE
  593. REGISTROS PRODUCTO%ROWTYPE;
  594. precio_prod_invalido EXCEPTION;
  595. NUM_ERROR NUMBER;
  596. BEGIN
  597.              
  598.                REGISTROS.CODPROD:=8;
  599.                REGISTROS.NOMPROD:= 'MOTHERBOARD BIOSTAR A15';
  600.                REGISTROS.PRECIO :=65;
  601.                
  602.                IF REGISTROS.PRECIO > 0 THEN
  603.                       INSERT INTO PRODUCTO VALUES REGISTROS;
  604.                      
  605.               ELSE
  606.                         RAISE precio_prod_invalido;
  607.                    
  608.               END IF;
  609.              
  610.               NUM_ERROR := SQLCODE;
  611.              
  612.               EXCEPTION
  613.                  WHEN   precio_prod_invalido  THEN
  614.                  NUM_ERROR := SQLCODE;
  615.                  DBMS_OUTPUT.PUT_LINE(' PRECIO INVALIDO :'||TO_CHAR( NUM_ERROR));
  616.                  RAISE_APPLICATION_ERROR(-20001,' ERROR : PRECIO NEGATIVO ');
  617.                  
  618. END;
  619. /
  620.  
  621. 39. Crear un procedimiento InsertaProd para insertar un producto. Usar tres parámetros,
  622. uno para cada atributo (código, nombre, precio).
  623.  
  624. CREATE OR REPLACE  PROCEDURE  InsertaProd (CODIGO INTEGER, NOMBRE VARCHAR2, PRECIO NUMBER)
  625. IS
  626. BEGIN
  627.  
  628.     INSERT INTO PRODUCTO VALUES(CODIGO,NOMBRE,PRECIO);
  629.  
  630.  
  631. END;
  632. /
  633.  
  634. 40. Revisar si hubo errores de compilación en la creación del procedimiento, y obtener la información sobre el procedimiento
  635. usando las tablas del catálogo USER_PROCEDURES y USER_OBJECTS (o su SINónimo OBJ).
  636.  
  637.  
  638. SHOW ERRORS;
  639.  
  640. Resultado :
  641. No hay Errores
  642.  
  643. OBTENIENDO INFORMACION  DESDE USER_PROCEDURES
  644.  
  645. SELECT * FROM USER_PROCEDURES   WHERE   OBJECT_NAME='INSERTAPROD' ;
  646.  
  647.  
  648. OBTENIENDO INFORMACION DESDE USER_OBJECTS
  649.  
  650. SELECT * FROM USER_OBJECTS  WHERE OBJECT_NAME='INSERTAPROD' ;
  651.  
  652.  
  653. 41. Examinar la estructura de la tabla USER_SOURCE y usarla para obtener el código fuente PL/SQL del procedimiento InsertaProd
  654.  
  655. Examinando Estructura de la tabla USER_SOURCE :
  656.  
  657. DESCRIBE USER_SOURCE;
  658. SELECT * FROM USER_SOURCE;
  659.  
  660. Obteniendo el Codigo Fuente del Procedimiento InsertProd :
  661.  
  662. SELECT LINE, TEXT  FROM USER_SOURCE WHERE  NAME='INSERTAPROD';
  663.  
  664.  
  665. 42. Ejecutar el procedimiento, insertando un producto mediante CALL y otro usando EXEC
  666.  
  667. CALL  InsertaProd(10,'TORRE 100 DVD ORACLE',20);
  668.  
  669. EXEC InsertaProd(11,'MOUSE INALAMBRICO MICROSOFT',25);
  670.  
  671.  
  672. 43. Averiguar que ocurre si creamos un bloque PL/SQL en el que insertamos varios productos llamando al procedimiento InsertaProd,
  673. pero una de las llamadas al procedimiento falla. Por ejemplo, trata de insertar la misma fila 2 veces.
  674.  
  675.  
  676. Informe de errores despues de ejecutar el bloque PL/SQL:
  677.  
  678. ORA-00001: restricción única (OWN_GUIA5.PK_CODIGO_PROD) violada
  679. ORA-06512: en "OWN_GUIA5.INSERTAPROD"
  680. 00001. 00000 -  "unique constraint (%s.%s) violated"
  681.  
  682. El bloque PL/SQL se ejecuta con errores y ninguna de las llamadas al procedimiento InsertaProd se realiza
  683. correctamente porque existen 2 filas que tienen el mismo valor en el campo CODPROD y este campo  contiene una restricción
  684. que no permite valores duplicados porque es una clave primaria.
  685. Las llamadas al procedimiento InsertaProd se ejecutaran exitosamente si los valores que contengan en el campo CODPROD
  686. no coincidan con un existente.
  687.  
  688.  
  689. 44. Intentar crear otro procedimiento InsertaProd que inserte un producto tomando como único parámetro un registro de tipo producto.
  690.  
  691. CREATE OR REPLACE PROCEDURE  InsertaProd(REGISTRO PRODUCTO%ROWTYPE)
  692. IS
  693.  
  694. BEGIN
  695.           INSERT INTO PRODUCTO VALUES REGISTRO;
  696.            
  697. END;
  698. /
  699.  
  700. 45. Crea un procedimiento ListaProds que toma como parámetro un valor numérico y lista todos los productos
  701. con precio mayor o igual a ese valor
  702.  
  703. CREATE OR REPLACE PROCEDURE ListaProds(VALOR NUMBER)
  704. IS
  705. CURSOR  C_REGISTROS IS SELECT  NOMPROD FROM PRODUCTO WHERE PRECIO >=VALOR;
  706. BEGIN
  707.        
  708.       FOR i IN  C_REGISTROS LOOP
  709.            DBMS_OUTPUT.PUT_LINE( TO_CHAR(i.NOMPROD) );
  710.            
  711.       END LOOP;
  712.  
  713. END;
  714. /
  715.  
  716. 46. Crear una función triple que devuelva el triple del número que toma como argumento
  717.  
  718. CREATE OR REPLACE FUNCTION TRIPLE(NUMERO NUMBER)
  719. RETURN NUMBER
  720. IS
  721. BEGIN
  722.                
  723.             RETURN (NUMERO * 3);
  724. END;
  725. /
  726.  
  727. 47. Crear una función PVP que toma como argumento un precio (de coste) del producto y devuelve el precio de venta al público,
  728. que resulta de aplicarle a ese precio de coste un margen comercial del 20%.
  729.  
  730. CREATE OR REPLACE FUNCTION PVP(PRECIO_COSTE NUMBER)
  731. RETURN NUMBER
  732. IS
  733. MARGEN_COMERCIAL NUMBER;
  734. P_VENTA_PUBLICO NUMBER;
  735. BEGIN
  736.           MARGEN_COMERCIAL := (PRECIO_COSTE * 0.20);
  737.           P_VENTA_PUBLICO:= PRECIO_COSTE + MARGEN_COMERCIAL;
  738.          
  739.           RETURN P_VENTA_PUBLICO;
  740.  
  741. END;
  742. /
  743.  
  744. 48. Crea una vista VPRODUCTO que obtenga todos los datos de los productos más el precio de venta al público.
  745.  
  746. CREATE VIEW VPRODUCTO AS
  747. SELECT CODPROD, NOMPROD, PRECIO, PVP(PRECIO) AS P_VENTA_PUBLICO FROM PRODUCTO;
  748.  
  749.  
  750. 49. Examinar los datos de la vista VPRODUCTO. Modificar la función PVP para que aplique un margen del 22%,
  751. y vuelve a examinar los datos de la vista.
  752.  
  753. Examinando datos de la vista :
  754.  
  755. SELECT * FROM VPRODUCTO;  /* MUESTRA PRECIO DE VENTA AL PUBLICO CON MARGEN DEL 20% */
  756.  
  757.  
  758. Modificando la funcion PVP para aplicar margen del 22% :
  759.  
  760. CREATE OR REPLACE FUNCTION PVP(PRECIO_COSTE NUMBER)
  761. RETURN NUMBER
  762. IS
  763. MARGEN_COMERCIAL NUMBER;
  764. P_VENTA_PUBLICO NUMBER;
  765. BEGIN
  766.           MARGEN_COMERCIAL := (PRECIO_COSTE * 0.22);
  767.           P_VENTA_PUBLICO:= PRECIO_COSTE + MARGEN_COMERCIAL;
  768.          
  769.           RETURN P_VENTA_PUBLICO;
  770.  
  771. END;
  772. /
  773.  
  774. Examinando datos de la vista :
  775.  
  776. SELECT * FROM VPRODUCTO;  /* MUESTRA PRECIO DE VENTA AL PUBLICO CON MARGEN DEL 22% */
  777.  
  778.  
  779. 50. Crear un paquete (PACKAGE) gestprod que usará para gestionar los productos. Debe incluir las signaturas de:
  780.  
  781. - Dos procedimientos InsertaProd, uno que tome 3 parámetros (código, nombre y precio) y otro que tome
  782. solo un parámetro: un registro de tipo producto.
  783.  
  784. - Una función BorraProd que borre un producto. Devolverá un valor booleano, indicando si borro el producto o no (porque no existía)
  785.  
  786. CREATE OR REPLACE PACKAGE gestprod AS
  787.  
  788. PROCEDURE  InsertaProd (CODIGO INTEGER, NOMBRE VARCHAR2, PRECIO NUMBER);
  789. PROCEDURE  InsertaProd(REGISTRO PRODUCTO%ROWTYPE);
  790. FUNCTION     BorraProd(CODIGO INTEGER) RETURN BOOLEAN;
  791.  
  792. END  gestprod;
  793. /
  794.  
  795. 51. Crea el cuerpo del paquete (PACKAGE BODY) para el paquete gestprod.
  796.  
  797. CREATE OR REPLACE PACKAGE BODY  gestprod AS
  798.  
  799. PROCEDURE  InsertaProd (CODIGO INTEGER, NOMBRE VARCHAR2, PRECIO NUMBER)
  800. IS
  801. BEGIN
  802.  
  803.     INSERT INTO PRODUCTO VALUES(CODIGO,NOMBRE,PRECIO);
  804.  
  805. END InsertaProd;
  806.  
  807. PROCEDURE  InsertaProd(REGISTRO PRODUCTO%ROWTYPE)
  808. IS
  809.  
  810. BEGIN
  811.           INSERT INTO PRODUCTO VALUES REGISTRO;
  812.            
  813. END InsertaProd;
  814.  
  815. FUNCTION BorraProd(CODIGO INTEGER)
  816. RETURN BOOLEAN
  817. IS
  818. EXISTE INTEGER;
  819. ELIMINADO BOOLEAN;
  820. BEGIN
  821.  
  822.           SELECT COUNT(*) INTO EXISTE FROM PRODUCTO WHERE CODPROD=CODIGO;
  823.      
  824.           IF EXISTE = 0 THEN
  825.                    ELIMINADO:= FALSE;
  826.                  
  827.           ELSE
  828.                   DELETE FROM PRODUCTO WHERE CODPROD=CODIGO;
  829.                   ELIMINADO:= TRUE;
  830.                
  831.           END IF;
  832.          
  833.           RETURN ELIMINADO;        
  834.  
  835. END BorraProd;
  836.  
  837. END  gestprod;
  838. /
  839.  
  840. 52. Crear un TRIGGER que fuerce a que los precios de los productos sean positivos. Controla solo las modificaciones (UPDATE) de datos.
  841.  
  842. CREATE OR REPLACE TRIGGER PRECIO_POSITIVO_UPDATE
  843. BEFORE  UPDATE  ON PRODUCTO  
  844. FOR EACH ROW
  845. DECLARE
  846. PRECIO_POSITIVO NUMBER(8,2);
  847. BEGIN
  848.          PRECIO_POSITIVO:=ABS(:NEW.PRECIO);
  849.         :NEW.PRECIO:=PRECIO_POSITIVO;
  850. END ;
  851. /
  852.  
  853.  
  854. 53. Crear otro TRIGGER que fuerce a que los precios de los productos sean positivos, pero en este caso controla solo las inserciones
  855.  
  856. CREATE OR REPLACE TRIGGER PRECIO_POSITIVO_INSERT
  857. BEFORE  INSERT  ON PRODUCTO  
  858. FOR EACH ROW
  859. DECLARE
  860. PRECIO_POSITIVO NUMBER(8,2);
  861. BEGIN
  862.          PRECIO_POSITIVO:=ABS(:NEW.PRECIO);
  863.         :NEW.PRECIO:=PRECIO_POSITIVO;
  864. END ;
  865. /
  866.  
  867.  
  868. 54. Repitir el Ejercicio 32, añadiendo de nuevo la restricción CHECK que comprueba que los precios de los productos son positivos.
  869. Ahora compruebe que se activa antes, la restricción o el TRIGGER
  870.  
  871. ALTER TABLE PRODUCTO
  872. ADD CONSTRAINT c_precio_positivo CHECK(PRECIO > 0);
  873.  
  874. Se activa primero el TRIGGER  porque tiene el modificador BEFORE y antes de hacer
  875. la inserción ejecuta lo que esta dentro del cuerpo del TRIGGER por lo cual el precio del producto
  876. se fuerza a que siempre sea  positivo usando la funcion ABS.
  877.  
  878. 55. Comprobar que orden sigue Oracle en la activación de 2 triggers que comparten tabla, evento, granularidad y tiempo de activación
  879.  
  880. Para comprobar el orden activación de triggers  se creo el TRIGGER PRECIO_INCREMENTO,
  881. el cual incrementa el precio del producto en un 5% :
  882.  
  883. CREATE OR REPLACE TRIGGER PRECIO_INCREMENTO
  884. BEFORE  INSERT ON PRODUCTO  
  885. FOR EACH ROW
  886. DECLARE
  887. P_INCREMENTO NUMBER(8,2);
  888. RESULTADO NUMBER(8,2);
  889. INCREMENTO NUMBER(8,2):=0.05;
  890. BEGIN
  891.          
  892.         P_INCREMENTO:= :NEW.PRECIO * INCREMENTO;
  893.         RESULTADO:= :NEW.PRECIO + P_INCREMENTO;
  894.         :NEW.PRECIO:= RESULTADO;
  895.        
  896. END ;
  897. /
  898.  
  899. Se inserto 1 registro en la tabla producto en el cual el precio del producto es negativo
  900.  
  901. CALL gestprod.InsertaProd(20,'DVD-ROM',-60.55);
  902.  
  903. El orden de activación de TRIGGER se realizo de la siguiente manera:
  904. Se activo el primer TRIGGER que se creo para la tabla producto que comparte el evento INSERT  (TRIGGER PRECIO_POSITIVO_INSERT) este
  905. cambio el precio del producto a positivo, luego se ejecuto el segundo TRIGGER que creo para la tabla PRODUCTO que comparte el mismo evento
  906. el cual es el TRIGGER PRECIO_INCREMENTO.
  907.  
  908.  
  909.  
  910. 56. Cree las tablas para almacenar facturas y líneas de factura
  911.  
  912.  Tabla Facturas :
  913.  
  914. CREATE TABLE  FACTURAS(
  915. NUMERO INTEGER CONSTRAINT PK_NUMERO_FACTURA PRIMARY KEY,
  916. FECHA DATE DEFAULT(SYSDATE),
  917. TOTAL NUMBER(8,2)
  918. );
  919.  
  920. Tabla Lineas :
  921.  
  922. CREATE TABLE LINEAS(
  923. NUMFAC INTEGER NOT NULL CONSTRAINT FK_NUMERO_FACTURA
  924. REFERENCES FACTURAS(NUMERO),
  925. NUMLI INTEGER NOT NULL,
  926. CODPROD INTEGER NOT NULL  CONSTRAINT FK_CODIGO_PROD
  927. REFERENCES PRODUCTO(CODPROD),
  928. CANTIDAD INTEGER NOT NULL,
  929. PRECIO NUMBER(8,2),
  930. SUBTOTAL NUMBER(8,2)
  931. );
  932.  
  933. 57. Asegurar de que cuando se añade una factura el total sea 0.
  934.  
  935. CREATE OR REPLACE TRIGGER TF_TOTAL_CERO
  936. BEFORE  INSERT ON FACTURAS  
  937. FOR EACH ROW
  938. BEGIN
  939.         :NEW.TOTAL:=0;
  940. END;
  941. /
  942.  
  943. 58. Cuando se añade una línea de factura, debe especificarse (entre otras cosas) el código de producto y la cantidad. Crea un TRIGGER t_subtotal_ins
  944. para que tanto el precio como el subtotal de esa línea se cubran automáticamente
  945.  
  946. CREATE OR REPLACE TRIGGER t_subtotal_ins
  947. BEFORE  INSERT ON LINEAS
  948. FOR EACH ROW
  949. DECLARE
  950. PRECIO_PRODUCTO  NUMBER(8,2);
  951. SUBTOTAL NUMBER(8,2);
  952. BEGIN
  953.    
  954.     /* PVP : FUNCION   QUE CALCULA EL PRECIO DE VENTA AL PUBLICO */
  955.      SELECT PVP(PRECIO) INTO PRECIO_PRODUCTO  FROM PRODUCTO WHERE CODPROD=:NEW.CODPROD;
  956.      
  957.      :NEW.PRECIO:=PRECIO_PRODUCTO;
  958.    
  959.      SUBTOTAL:= (:NEW.CANTIDAD * PRECIO_PRODUCTO);
  960.      
  961.      :NEW.SUBTOTAL:=SUBTOTAL;
  962.      
  963. END ;
  964. /
  965.  
  966. 59. Crea otro TRIGGER t_subtotal_upd, similar al realizado para el Ejercicio 58, para realizar el mismo cometido
  967. cuando se modifica una línea de factura.
  968.  
  969. CREATE OR REPLACE TRIGGER t_subtotal_upd
  970. BEFORE  UPDATE  ON LINEAS
  971. FOR EACH ROW
  972. DECLARE
  973. PRECIO_PRODUCTO  NUMBER(8,2);
  974. SUBTOTAL NUMBER(8,2);
  975. BEGIN
  976.  
  977.      /* PVP : FUNCION   QUE CALCULA EL PRECIO DE VENTA AL PUBLICO */
  978.      SELECT PVP(PRECIO) INTO PRECIO_PRODUCTO  FROM PRODUCTO WHERE CODPROD=:NEW.CODPROD;
  979.      
  980.      :NEW.PRECIO:=PRECIO_PRODUCTO;
  981.    
  982.      SUBTOTAL:= (:NEW.CANTIDAD * PRECIO_PRODUCTO);
  983.      
  984.      :NEW.SUBTOTAL:=SUBTOTAL;
  985.      
  986. END ;
  987. /
  988.  
  989. 60. Combina los triggers de los ejercicios 58 y 59 en un ´unico TRIGGER t_subtotal. Decidir si se debe eliminar o deshabilitar
  990. los triggers t_subtotal_ins y t_subtotal_upd una vez se haya creado.
  991.  
  992.  
  993. CREATE OR REPLACE TRIGGER t_subtotal
  994. BEFORE  INSERT OR  UPDATE  ON LINEAS
  995. FOR EACH ROW
  996. DECLARE
  997. PRECIO_PRODUCTO  NUMBER(8,2);
  998. SUBTOTAL NUMBER(8,2);
  999. BEGIN
  1000.  
  1001.      /* PVP : FUNCION   QUE CALCULA EL PRECIO DE VENTA AL PUBLICO */
  1002.      SELECT PVP(PRECIO) INTO PRECIO_PRODUCTO  FROM PRODUCTO WHERE CODPROD=:NEW.CODPROD;
  1003.      
  1004.      :NEW.PRECIO:=PRECIO_PRODUCTO;
  1005.    
  1006.      SUBTOTAL:= (:NEW.CANTIDAD * PRECIO_PRODUCTO);
  1007.      
  1008.      :NEW.SUBTOTAL:=SUBTOTAL;
  1009.      
  1010. END;
  1011. /
  1012.  
  1013. Se eliminaran los triggers  t_subtotal_ins y t_subtotal_upd  no son necesarios
  1014. el TRIGGER  t_subtotal se encargara de obtener el precio del producto y calcular el subtotal
  1015. y se disparará cuando se realiza una inserción ó actualización.
  1016.  
  1017. DROP TRIGGER  t_subtotal_ins;
  1018. DROP TRIGGER t_subtotal_upd;
  1019.  
  1020.  
  1021. 61. Crear el(los) TRIGGER(s) necesarios para mantener correctamente actualizado el total de la factura.
  1022.  
  1023. CREATE OR REPLACE TRIGGER TOTAL_FACTURA
  1024. BEFORE  INSERT OR UPDATE OR DELETE  ON LINEAS
  1025. FOR EACH ROW
  1026. DECLARE
  1027. PRECIO_PRODUCTO  NUMBER(8,2);
  1028. SUBTOTAL NUMBER(8,2);
  1029. TOTAL_ACTUAL NUMBER(8,2);
  1030. TOTAL_FACTURA NUMBER(8,2);
  1031. TOTAL_ANTERIOR NUMBER(8,2);
  1032. BEGIN
  1033.      
  1034.    
  1035.      IF INSERTING THEN
  1036.                  
  1037.             SELECT PVP(PRECIO) INTO PRECIO_PRODUCTO  FROM PRODUCTO WHERE CODPROD=:NEW.CODPROD;
  1038.             SUBTOTAL:= (:NEW.CANTIDAD * PRECIO_PRODUCTO);
  1039.            
  1040.             SELECT TOTAL INTO TOTAL_ACTUAL FROM   FACTURAS WHERE NUMERO=:NEW.NUMFAC;
  1041.             TOTAL_FACTURA:= (SUBTOTAL + TOTAL_ACTUAL);
  1042.            
  1043.             UPDATE FACTURAS SET TOTAL=TOTAL_FACTURA  WHERE NUMERO=:NEW.NUMFAC;
  1044.    
  1045.     ELSIF UPDATING THEN
  1046.                        
  1047.              SELECT PVP(PRECIO) INTO PRECIO_PRODUCTO  FROM PRODUCTO WHERE CODPROD=:NEW.CODPROD;
  1048.             SUBTOTAL:= (:NEW.CANTIDAD * PRECIO_PRODUCTO);
  1049.            
  1050.             SELECT TOTAL INTO TOTAL_ACTUAL FROM   FACTURAS WHERE NUMERO=:NEW.NUMFAC;
  1051.             TOTAL_ANTERIOR := (TOTAL_ACTUAL - :OLD.SUBTOTAL);
  1052.            
  1053.             TOTAL_FACTURA:= (TOTAL_ANTERIOR + SUBTOTAL);
  1054.             UPDATE FACTURAS SET TOTAL=TOTAL_FACTURA  WHERE NUMERO=:NEW.NUMFAC;
  1055.        
  1056.     ELSIF DELETING THEN
  1057.              
  1058.             SELECT TOTAL INTO TOTAL_ACTUAL FROM   FACTURAS WHERE NUMERO=:OLD.NUMFAC;
  1059.             TOTAL_FACTURA := (TOTAL_ACTUAL - :OLD.SUBTOTAL);
  1060.          
  1061.             UPDATE FACTURAS SET TOTAL=TOTAL_FACTURA  WHERE NUMERO=:OLD.NUMFAC;
  1062.          
  1063.     END IF;
  1064.      
  1065. END ;
  1066. /
Advertisement
Add Comment
Please, Sign In to add comment