lunes, 30 de diciembre de 2013

crear calendario ex1

/** 
 * Realizar un procedimiento que realize todas las combinaciones posibles de 
 * emfentamientos entre equipos, teniendo en cuenta que un equipo no se podrá 
 * enfrentar contra si mismo y cada enfrentamiento entre equipos difenrentes 
 * supone dos enfrentamientos uno como local y otro como visitante
 */


CREATE OR REPLACE PROCEDURE crear_calendario IS
BEGIN
  FOR I IN (SELECT * FROM equipos) LOOP
    FOR J IN (SELECT * FROM equipos) LOOP        
      IF I.codequipo != J.codequipo THEN
        DBMS_OUTPUT.PUT_LINE('Local: ' || I.codequipo || '. ' || I.nombre || ' *** Visitante: ' || J.codequipo || '. ' || J.nombre );
      END IF;
    END LOOP;
  END LOOP;
END crear_calendario;


/* Para mostrar */
SET SERVEROUTPUT ON

BEGIN
  crear_calendario();
END;

lunes, 9 de diciembre de 2013

proc jugadores_todos

CREATE OR REPLACE
PROCEDURE jugadores_todos IS

CURSOR c_jugadores IS 
  SELECT * FROM jugadores j;

lm_equipo VARCHAR2(400);

BEGIN
  FOR I IN c_jugadores LOOP
    
    SELECT nombre
    INTO lm_equipo
    FROM equipos e
    WHERE e.codequipo = I.codequipo;
    
    DBMS_OUTPUT.PUT_LINE('Nombre de jugador: '||I.nombre);
    DBMS_OUTPUT.PUT_LINE('Fecha Nacimiento '||I.fechanacimiento);
    DBMS_OUTPUT.PUT_LINE('Posicion: '||I.demarcacion);
    DBMS_OUTPUT.PUT_LINE('Equipo: '|| lm_equipo);
    DBMS_OUTPUT.PUT_LINE('');
    
  END LOOP;

END;


/** Para mostrar**/
EXECUTE jugadores_todos;

Strings Ejemplos

SUBSTR Obtiene una parte de una expresion, desde una posición de inicio hasta una determinada longitud.

SUBSTR(<expresion>, <posicion_ini>, <longitud> )

SELECT SUBSTR('HOLA MUNDO', 6, 5) -- Devuelve MUNDO
      FROM DUAL;




INSTR Busca una cadena de caracteres dentro de otra. Devuelve la posicion de la ocurrencia de la cadena buscada.

INSTR(<char>, <search_string>, <startpos>, <occurrence> )

SELECT INSTR('AQUI ES DONDE SE BUSCA', 'BUSCA', 1, 1 )
FROM DUAL;

domingo, 8 de diciembre de 2013

factorial

//Consigue el factorial de un numero 

CREATE OR REPLACE
FUNCTION factorial (obj IN PLS_INTEGER) RETURN PLS_INTEGER IS
num PLS_INTEGER := 1;
res PLS_INTEGER := 1;


BEGIN
  DBMS_OUTPUT.PUT_LINE('Numeros factoriales');
  WHILE res < obj LOOP
    res := res * num;
    DBMS_OUTPUT.PUT_LINE(num);
    num := num + 1;
  END LOOP;
  
  IF res = obj THEN
    DBMS_OUTPUT.PUT_LINE('El resultado es ');
    RETURN res;
  ELSE
    DBMS_OUTPUT.PUT_LINE('El resultado no dio exacto : ');
    RETURN res;
  END IF;

  
END;


/** Para mostrarlo**/
SET SERVEROUTPUT ON
DECLARE
  x PLS_INTEGER := 180;

BEGIN
DBMS_OUTPUT.PUT_LINE(factorial(x));

END;

ficha_jugador examen

// Crea una funcion, a la que introduciendo un codigo de jugador nos devuelva.
//Nombre: <nombre>  Fecha nac: <fechanac>  Posicion: <demarcacion>

create or replace 
FUNCTION ficha_jugador(cj IN jugadores.codjugador%TYPE) RETURN VARCHAR IS
ficha VARCHAR(3000);

BEGIN
  SELECT 'Nombre: ' || j.nombre ||'  Fecha nacimento: ' || j.fechanacimiento || '  Posicion: ' || j.demarcacion

  INTO ficha
  FROM jugadores j
  WHERE j.codjugador = cj;
  
  COMMIT;
  
  RETURN ficha;

  EXCEPTION
    WHEN NO_DATA_FOUND THEN

      RETURN 'No existe ese codigo de jugador';


END ficha_jugador;



/**  Para mostrarlo **/
DECLARE
x NUMBER := 2;

BEGIN
DBMS_OUTPUT.PUT_LINE(ficha_jugador(x));

END;

BA Array bucle mostrar

//Crea un Bloque anonimo donde tengas un array de 3 posiciones y lo recorras con un bucle.

DECLARE
   TYPE varray_mvps IS VARRAY(3) OF VARCHAR2 (10);
   ARRAY varray_mvps := varray_mvps('Matt', 'Joanne', 'Robert');

BEGIN
   FOR i IN 1..ARRAY.COUNT LOOP
       DBMS_OUTPUT.PUT_LINE(ARRAY(i));
   END LOOP;
END;

TEORIA rollback commit


Comandos utilizados para el control de transacciones

Commit
Este comando da por concluida la transacción actual y hace definitivos los cambios realizados liberando las filas bloqueadas. Sólo después de que se ejecute commit tendremos acceso a los datos modificados.


Rollback

Este comando da por concluida la transacción actual y deshace los cambios que se pudiesen haber producido en la misma, liberando las filas bloqueadas. Se utiliza especialmente cuando no se puede concluir una transacción porque se han levantado excepciones.


Savepoint

Se utiliza para poner marcas o puntos de salvaguarda al procesar transacciones. Se utiliza junto con rollback permitiendo deshacer cambios hasta los savepoint.

El número de savepoint esta limitado a 5 por sesión pero lo podemos modificar con la siguiente sentencia:


savepoint numero;


Rollback implicito
Este comando se ejecuta cuando un programa almacenado (procedimiento o función) falla y no se controla la excepción que produjo el fallo. Pero si en el programa tenemos un commit estos cambios no serán deshechos


Rollback to
Deshace el trabajo realizado después del punto indicado. Pero no se confirma el trabajo hecho hasta el savepoint. La transacción no finaliza hasta que se ejecuta un comando de control de transacciones o hasta que finaliza la sesión.

Os dejo a continuación un ejemplo bastante completo de lo que seria el control de transacciones:

create or replace procedure prueba (nfilas number)
as
   begin
      savepoint ninguna;
      insert into tmp values ('primera fila');
      savepoint una;
      insert into tmp values ('segunda fila');
      savepoint dos;
      if nfilas=1 then
         rollback to una;
      else if nfilas=2 then
         rollback to dos;
      else
         rollback to ninguna;
      end if;
      commit;
      exception
         when other then
            rollback
end prueba
;

fun reverse cadena

//Crea una funcion a la que le pases una cadena y retorne al reves.

CREATE OR REPLACE FUNCTION al_reves (cadena IN VARCHAR2) RETURN VARCHAR2 IS
aux VARCHAR2(100) := cadena;

BEGIN
  SELECT reverse(aux)
  INTO aux
  FROM dual;
  
  DBMS_OUTPUT.PUT_LINE(aux);
END;


/** Para mostrarlo**/

SET SERVEROUTPUT ON
DECLARE
x VARCHAR2(100) := 'pepe mola ';

BEGIN
DBMS_OUTPUT.PUT_LINE(al_reves(x));

END;

sábado, 7 de diciembre de 2013

pack inventoryops

/**  * 005 InventoryOps  */

CREATE OR REPLACE PACKAGE InventoryOps IS

  -- Modifies the inventory data for the specified book
  PROCEDURE UpdateIsbn(p_isbn IN INVENTORY.ISBN%TYPE
                      , p_status IN INVENTORY.STATUS%TYPE
                      , p_statusdate IN INVENTORY.STATUS_DATE%TYPE
                      , p_amount IN INVENTORY.AMOUNT%TYPE);
      
      
  -- Deletes the inventory data for the specified book             
  PROCEDURE Delete_isbn(p_isbn IN INVENTORY.ISBN%TYPE);
  
  -- Exception raised by UpdateISBN or DeleteISBN when the specified ISBN
  -- is not in the inventory table
  e_isbn_not_found  EXCEPTION;
  
  
  TYPE isbn_table IS TABLE OF inventory.isbn%TYPE INDEX BY BINARY_INTEGER;
  
  -- Returns an array containing the books with the specified status
  PROCEDURE StatusList(p_status IN INVENTORY.STATUS%TYPE
                      , p_books OUT ISBN_TABLE
                      , p_numbooks OUT BINARY_INTEGER);


END InventoryOps;
/

CREATE OR REPLACE PACKAGE BODY InventoryOps IS

  /**
  PROCEDURE ValidateStatus(p_status IN INVENTORY.STATUS%TYPE) IS
  BEGIN
    IF p_status = 'IN STOCK' OR p_status = 'BACKORDERED' OR p_status = 'FUTURE' THEN
      RETURN;
    ELSE
      RAISE_APPLICATION_ERROR(20000, 'Suplied status ' || p_status || ' is not valid');
    END IF;
  END ValidateStatus;
  */

 PROCEDURE UpdateIsbn(p_isbn IN INVENTORY.ISBN%TYPE
                      , p_status IN INVENTORY.STATUS%TYPE
                      , p_statusdate IN INVENTORY.STATUS_DATE%TYPE
                      , p_amount IN INVENTORY.AMOUNT%TYPE) IS
  BEGIN
     -- ValidateStatus(p_status);
     UPDATE inventory
     SET status = p_status, status_date = p_statusdate, amount = p_amount
     WHERE isbn = p_isbn;
     
     IF SQL%ROWCOUNT = 0 THEN
      RAISE e_isbn_not_found;
     END IF;
     
  END UpdateIsbn;
  
  PROCEDURE Delete_isbn(p_isbn IN INVENTORY.ISBN%TYPE) IS
  BEGIN
    DELETE FROM inventory
    WHERE isbn = p_isbn;
    
    IF SQL%ROWCOUNT = 0 THEN
      RAISE e_isbn_not_found;
    END IF;
  END Delete_isbn;
  
  PROCEDURE StatusList(p_status IN INVENTORY.STATUS%TYPE
                      , p_books OUT ISBN_TABLE
                      , p_numbooks OUT BINARY_INTEGER) IS
                      
    l_isbn INVENTORY.ISBN%TYPE;
    
    CURSOR books_cursor IS 
      SELECT isbn 
      FROM inventory i 
      WHERE i.status = p_status;
  
BEGIN
    -- ValidateStatus(p_status);
    p_numbooks := 0;
    
    OPEN books_cursor;
    
    LOOP
      FETCH books_cursor 
      INTO l_isbn;
      EXIT WHEN books_cursor%NOTFOUND;
    
      p_numbooks := p_numbooks + 1;
      p_books(p_numbooks) := l_isbn;
      
    END LOOP;
    
    CLOSE books_cursor;
  END StatusList;
  
END InventoryOps;
/

viernes, 6 de diciembre de 2013

Proc cursor_jugadores_barcelona

create or replace 
PROCEDURE jugadores_all IS

--declarando cursor
  CURSOR cursor_jugadores IS
    SELECT codjugador, nombre
    FROM jugadores j
    WHERE codequipo=1;
    
  --variables para los campos
    v_codju VARCHAR2(4000);
    v_nombre VARCHAR2(4000);
    
    BEGIN
-- abrir cursor
      OPEN cursor_jugadores;

 --procesar cursor, fetch para recorrer el cursor     
      LOOP
        FETCH cursor_jugadores
          INTO v_codju, v_nombre;

--cuando salga, escribe las lineas        
        EXIT WHEN cursor_jugadores%NOTFOUND;
        
        DBMS_OUTPUT.PUT_LINE(v_codju || ' ' || v_nombre);      
      END LOOP;
    
    CLOSE cursor_jugadores;
    
    END jugadores_all;



/** Mostrar **/
BEGIN
  JUGADORES_ALL();
END;


proc 3 ex cursor

/**
 * 3. Codificar un procedimiento, llamado "incidencias_por_jugador", que indique 
 * el nombre de cada jugador y el número de incidencias que tiene, en caso de 
 * que su número de incidencias sea 0 el mensaje debe de decir 'El jugador <nombre> no tiene incidencias'
 */
CREATE OR REPLACE PROCEDURE incidencias_por_jugador IS

  -- Cursor que recorrera la tabla jugadores
  CURSOR c_jugadores IS
    SELECT * FROM jugadores j;
  
  -- Donde almacenaremos el número de incidencias por cada jugador
  ln_num_incidencias PLS_INTEGER := 0;

BEGIN

  -- Recorremos el cursor
  FOR I IN c_jugadores LOOP
    -- Por cada jugador contamos su número de incidencias
    SELECT COUNT(*) 
    INTO ln_num_incidencias  
    FROM incidencias inc 
    WHERE inc.codjugador = I.codjugador;
    
    -- Si son 0 mostramos un mensaje
    IF ln_num_incidencias = 0 THEN
      DBMS_OUTPUT.PUT_LINE('El jugador ' || I.nombre || ' no tiene incidencias');
    ELSE
      DBMS_OUTPUT.PUT_LINE(I.nombre || ': ' || ln_num_incidencias);
    END IF; 
  
  END LOOP; 

END incidencias_por_jugador;

jueves, 5 de diciembre de 2013

fun2 ex

CREATE OR REPLACE
FUNCTION del_inc(nin IN incidencias.numincidencia%TYPE) RETURN
VARCHAR IS

pepe VARCHAR(4000) := ' ';

BEGIN
  SELECT j.nombre || ' ' || j.demarcacion
  INTO pepe
  FROM  incidencias i, jugadores j
  WHERE i.numincidencia = nin AND i.codjugador = j.codjugador;
  
  DELETE
  FROM incidencias i
  WHERE i.numincidencia = nin;
  COMMIT;
  
  RETURN pepe;
  
  EXCEPTION
  WHEN NO_DATA_FOUND THEN
    RETURN 'NO EXISTE LA INCIDENCIA';

END del_inc;

/**Llamar a funcion **/
SET SERVEROUTPUT ON

BEGIN
DBMS_OUTPUT.PUT_LINE(del_inc(10000));

END;

proc1 ex


create or replace 
PROCEDURE swap(n1 IN OUT PLS_INTEGER, n2 IN OUT PLS_INTEGER) IS

 n3 PLS_INTEGER := n1;

BEGIN
n1 := n2;
n2 := n3;
DBMS_OUTPUT.PUT_LINE(n1 || n2);


END swap;


/**Para mostrarlo**/
SET SERVEROUTPUT ON
DECLARE
 x PLS_INTEGER := 8;
 y PLS_INTEGER := 9;

BEGIN
swap(x,y);

END;


-----------------------------------------------------------------

create or replace 
FUNCTION faciluno (cad IN OUT  VARCHAR2,cad2 IN OUT VARCHAR2) RETURN VARCHAR2 IS
  inter VARCHAR2(100) := cad;

 BEGIN
    cad := cad2;
    cad2 := inter;
    
    inter := cad;
    
  RETURN inter;

 END faciluno;


/** Para mostrarlo**/

SET SERVEROUTPUT ON

DECLARE
x VARCHAR2(100) := 'pepe';
y VARCHAR2(100) := 'jose';

BEGIN
DBMS_OUTPUT.PUT_LINE(faciluno(x,y));


END;




pack4 ex

/*
 * 4. Crear un paquete llamado "competición" en el que se defina,
 * una función llamada "get_partidos" dicha función ha de devolver los
 * 5 últimos partidos de una determinada competición.
 * La información a devolver deberá ser almacenada en una estructura de datos
 * de tipo VARRAY
 * El tipo de competición ha de ser validado, lanzando un error en caso de
 * introducir un tipo de competición no valido en la base de datos y mostrando
 * un error por pantalla
 */

CREATE OR REPLACE PACKAGE competicion IS

  -- Creación del tipo de datos de retorno
  TYPE varray_partidos IS VARRAY(5) OF PARTIDOS%ROWTYPE;

  -- Función que nos devolverá los 5 últimos partidos de una competición
 
FUNCTION get_partidos(pv_competicion IN VARCHAR) RETURN VARRAY_PARTIDOS;
 
   competicion_not_found  EXCEPTION;
 
END competicion;

/

CREATE OR REPLACE PACKAGE BODY competicion IS

  -- Cuerpo de GET_PARTIDOS
  FUNCTION get_partidos(pv_competicion IN VARCHAR) RETURN VARRAY_PARTIDOS IS
 
    /**
     * En este cursor seleccionamos los partidos de una determinada competición
     * y los ordenamos por fecha
     */

    CURSOR cur_partidos IS
      SELECT *
      FROM partidos p
      WHERE LOWER(p.competicion) = LOWER(pv_competicion)
      ORDER BY p.fecha DESC;
   
    -- Array donde almacenaremos los resultados
    l_array_partidos VARRAY_PARTIDOS;
   
    -- Variable donde almacenaremos los registros la tabla partido
    lr_partidos PARTIDOS%ROWTYPE;
   
    -- Contador de resgistros
    contador PLS_INTEGER := 0;
 

BEGIN
    -- En el caso de que la competición sea 'Liga' o 'Copa'
    IF LOWER(pv_competicion) = 'liga' OR LOWER(pv_competicion) = 'copa' THEN
      -- Inicializamos el array
      l_array_partidos := varray_partidos();
   
      -- Abrimos el cursor
      OPEN cur_partidos;
     
      LOOP
        -- Procesamiento de la línea
        FETCH cur_partidos INTO lr_partidos;
        /*
         * Exit si no encuentra datos o si contador es mayor
         * que el límite del array
         */

        EXIT WHEN cur_partidos%NOTFOUND OR contador >= l_array_partidos.LIMIT;
       
        -- Incrementamos el contador
        contador := contador + 1;
       
        -- Creamos la posición dentro del array
        l_array_partidos.EXTEND;
       
        -- Llenamos esa posición
        l_array_partidos(contador) := lr_partidos;
      END LOOP;
     
      -- Cerramos cursor
      CLOSE cur_partidos;
       
      -- Devolvemos el resultado
      RETURN l_array_partidos;
    ELSE -- Si no lanzamos excepción
      RAISE competicion_not_found;
    END IF;
   
  END get_partidos;

END competicion;

martes, 3 de diciembre de 2013

fun inverso sporting

create or replace 
FUNCTION INVERSO(v IN VARCHAR) RETURN VARCHAR IS 
  aux VARCHAR(4001);
  
  s CHAR(8) := 'SPORTING';
  size_sporting PLS_INTEGER := 0;
  posicion PLS_INTEGER;
    
BEGIN
  posicion := INSTR(UPPER(v), UPPER(s));
  size_sporting := LENGTH(s);
  
  FOR I IN 1 .. LENGTH(v) LOOP
    IF I >= posicion AND I <= posicion + size_sporting - 1 THEN
      aux := aux || UPPER(SUBSTR(v, I, 1));
    ELSE
      aux := aux || SUBSTR(v, I, 1);
    END IF;
  END LOOP;
  
  SELECT reverse(aux)
  INTO aux
  FROM dual;

  RETURN aux;
END INVERSO;



/**Llamar a la funcion**/
SELECT INVERSO('josemanuel') FROM DUAL;

proc cont_autores

CREATE OR REPLACE PROCEDURE CONT_AUTORES IS
  
CURSOR c_autores IS
    SELECT a.ID
           a.FIRST_NAME, 
           (SELECT COUNT(*) 
            FROM BOOKS b 
            WHERE b.author1 = a.ID OR b.author2 = a.ID OR b.author3 = a.ID) cont
    FROM AUTHORS a
    WHERE (SELECT COUNT(*) 
            FROM BOOKS b 
            WHERE b.author1 = a.ID OR b.author2 = a.ID OR b.author3 = a.ID) > 2
          AND ROWNUM < 5;

  lr_autor c_autores%ROWTYPE;

BEGIN

  OPEN c_autores;
  
  LOOP
    FETCH c_autores INTO lr_autor;
    EXIT WHEN c_autores%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(lr_autor.ID || ' ' || lr_autor.first_name || ' libros: ' || lr_autor.cont);
  END LOOP;
  
  CLOSE c_autores;

END;

lunes, 2 de diciembre de 2013

cursores explicitos funcionamiento

Cursores explícitos

Los cursores explícitos los utilizamos cuando tenemos consultas que nos devuelven más de una fila. 
Tenemos 4 operaciones básicas para trabajar con un cursor explícito. 
  1. Declaración del cursor: lo tenemos que declarar en la zona de declaraciones, con el siguiente formato:CURSOR <nombrecursor> IS <sentencia SELECT>;
  2. Apertura del cursor: Deberá colocarse en la zona de instrucciones, con el siguiente formato: 
    OPEN <nombrecursor>;
    Al hacerlo se ejecuta automáticamente la sentencia select y sus resultados se almacenan en las estructuras internas de memoria manejadas por el cursor.
  3. Recogida de información: Para recuperar la información anteriormente guardada en las estructuras de memoria interna tenemos que usar el siguiente formato: 
    FETCH <nombrecursor> INTO {<variable> | <listavariables>};
    Si tenemos una única variable que recoge los datos de todas las columnas, el formato de la variable seria el siguiente: 
    <variable> <nombrecursor>%ROWTYPE;
    Si tenemos una lista de variables, cada una recogerá la columna correspondiente de la cláusula select, por lo que serán del mismo tipo que las columnas.
  4. - Cierre del cursor: 
    CLOSE <nombrecursor>;
Ahora, veamos un ejemplo de utilización de cursores explícitos:
DECLARE   
   CURSOR C1 IS SELECT nombre, apellido FROM arbitro;
   Vnom VARCHAR2(12);
   Vape    VARCHAR2(20);
BEGIN
   OPEN C1;
   LOOP 
      FETCH C1 INTO Vnom, Vape;
      EXIT WHEN C1%NOTFOUND;
      DBMS_OUTPUT.PUT_LINE(Vnom || '' || Vapen);
   END LOOP;
   CLOSE C1;
END;

proc parametro if null

/** * 001 parameterModes */

CREATE OR REPLACE PROCEDURE ModeIn(p_parameter IN NUMBER) IS
  l_variable NUMBER := 0;

BEGIN

  DBMS_OUTPUT.PUT_LINE('Inside ModeIn:');

  IF p_parameter IS NULL THEN
    DBMS_OUTPUT.PUT_LINE('p_parameter is NULL');
  ELSE
    DBMS_OUTPUT.PUT_LINE('p_parameter = ' || p_parameter);
  END IF;
  
  l_variable := p_parameter;
  
  DBMS_OUTPUT.PUT_LINE('At end of ModeIn:');

 IF p_parameter IS NULL THEN
    DBMS_OUTPUT.PUT_LINE('p_parameter is NULL');
  ELSE
    DBMS_OUTPUT.PUT_LINE('p_parameter is =' || p_parameter);
  END IF;


END ModeIn;
/



/****  LLamando a la funcion ****/

SET SERVEROUTPUT ON

DECLARE
  l_in NUMBER := 1;
BEGIN
  DBMS_OUTPUT.PUT_LINE('Before calling ModeIn, l_In = ' || l_in);
  ModeIn(l_in);
  DBMS_OUTPUT.PUT_LINE('After calling ModeIn, l_in = ' || l_in);
END;
/


BEGIN
  ModeIn(3);
END;
/

proc addbook insert arrays tipos

CREATE OR REPLACE PROCEDURE AddBook(  p_isbn IN BOOKS.ISBN%TYPE
                                    , p_category IN BOOKS.CATEGORY%TYPE := 'Oracle Server'
                                    , p_title IN BOOKS.TITLE%TYPE
                                    , p_numpages IN BOOKS.NUM_PAGES%TYPE
                                    , p_price IN BOOKS.PRICE%TYPE
                                    , p_copyright IN BOOKS.COPYRIGHT%TYPE DEFAULT TO_NUMBER(TO_CHAR(SYSDATE, 'YYYY'))
                                    , p_author1 IN BOOKS.AUTHOR1%TYPE
                                    , p_author2 IN BOOKS.AUTHOR1%TYPE := NULL
                                    , p_author3 IN BOOKS.AUTHOR1%TYPE := NULL) IS
BEGIN
  INSERT INTO BOOKS(isbn, category, title, num_pages, price, copyright, author1, author2, author3)
  VALUES (p_isbn, p_category, p_title, p_num_pages, p_price, p_copyright, p_author1, p_author2, p_author2);
END;
/

BEGIN
  AddBook('0000000000', 'Oracle Basic', 'A Really Nifty Book', 500, 34.99, 2004, 1);
END;
/

BEGIN
  AddBook(  p_isbn => '000000000'
          , p_category => 'Oracle Basics'
          , p_title => 'A Really Nifty Book'
          , p_numpages => 500
          , p_price => 34.99
          , p_copyright => 2004
          , p_author1 => 1);
END;
/

BEGIN
  AddBook(  p_isbn => '000000000'
          , p_title => 'A Really Nifty Book'
          , p_numpages => 500
          , p_price => 34.99
          , p_author1 => 1);
END;
/