Oracle - Ayuda con un bloque SQL

 
Vista:

Ayuda con un bloque SQL

Publicado por Oscar (4 intervenciones) el 17/09/2010 21:48:56
Hola a todos.

Estoy intentando solucionar un ejercicio de PL/SQL y quisiera saber si alguien con conocimientos en el tema me puede colaborar. El asunto es el siguiente:

Tengo una BD en Oracle 10g con las tablas y sus respectivas columnas: AGENCIA (codigo_pk V20, nombre V30, dirNumero V40, dirBarrio V30, codCiudad_fk), RESERVA (codigo_pk V7, codAgencia_fk, cedCliente, placaCoche, fechaInicio, fechaFinal), CLIENTE (cedula_pk V15, nombre V30, apellido V30, dir_numero V30, dir_barrio V30) y COCHE (placa_pk V6, color V30, modelo N4, valorPrestamo N10, valorComercial N12, marca V30, codGaraje_uk).

Entonces, necesito mostrar la información del coche que más se reservó en un año determinado. Eso en un bloque PL/SQL y en otro bloque, poder incluir una nueva reserva, si me dan el nombre de la agencia, el nombre completo del cliente y la placa del coche.

Esto es lo que he intentadop hacer, pero nada:

para el primero:

VARIABLE mensaje VARCHAR2(300);

DECLARE

v_año VARCHAR2(4):=('&Año_Reserva:');
v_placa coche.placa%type;
v_num_veces NUMBER(4);

BEGIN

SELECT MAX(COUNT(*)) INTO v_num_veces, placacoche INTO v_placa
FROM reserva
GROUP BY placacoche
HAVING COUNT(placacoche) LIKE v_num_veces;
:mensaje:=v_num_veces;

END;

PRINT mensaje;

para lo segundo:

DECLARE

V_Agencia AGENCIA.nombre%TYPE:=UPPER('&NOMBRE_AGENCIA:');
V_Nombre_Cliente CLIENTE.nombre%TYPE:=UPPER('&NOMBRE_CLIENTE:');
V_Apellido_Cliente CLIENTE.apellido%TYPE:=UPPER('&APELLIDO_CLIENTE:');
V_Placa COCHE.placa%TYPE:=UPPER('&PLACA_COCHE:');
V_Fecha_Fin RESERVA.fechafinal%TYPE:=('&FECHA_FINAL:');
V_Cod_Reserva RESERVA.codigo%TYPE;
V_Cod_Agencia AGENCIA.codigo%TYPE;
V_Ced_Cliente CLIENTE.cedula%TYPE;

BEGIN

SELECT MAX(TO_NUMBER(codigo))+1 INTO V_Cod_Reserva FROM reserva;
SELECT codigo INTO V_Cod_Agencia FROM agencia WHERE UPPER(nombre) LIKE %V_Agencia%;
SELECT cedula INTO V_Ced_Cliente FROM cliente WHERE UPPER(nombre) LIKE %V_Nombre_Cliente% AND UPPER(apellido) LIKE %V_Apellido_Cliente%;
SELECT placa INTO v_Placa FROM coche WHERE UPPER(placa) LIKE V_Placa;
INSERT INTO reserva VALUES
(V_Cod_Reserva,V_Cod_Agencia,V_Ced_Cliente,V_Placa,SYSDATE,TO_DATE(V_Fecha_Fin));

COMMIT;
END;

Les agradezco cualquier ayuda. (Súper urgente!)
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

RE:Ayuda con un bloque SQL

Publicado por Patricia Dávila (3 intervenciones) el 23/11/2010 00:18:49
Hola Oscar, soy estudiante de pl/sq y bueno te comento que el primer caso lo he resuelto de la siguiente manera.

1- El coche que más se reservó en un año determinado, como ejemplo puse el año 2010.

V_placa varchar2(300);
Cuantos number;

Cursor C is Select placaCoche, count(*) cuantos from reserva where fecha_inicio=to_char(fecha_inicio,'yyyy')='2010'
group by placacoche order by count(*) desc;

Begin
Open c;
Fetch C into v_placa,cuantos;
Close c;
Return v_placa, cuantos;
End;
/

2- El segundo en principio te tendría que funcionar.

Incluir una reserva, si me dan el nombre de la agencia, el nombre completo del cliente y la placa del coche.

DECLARE

V_Agencia AGENCIA.nombre%TYPE:=UPPER('&NOMBRE_AGENCIA:');
V_Nombre_Cliente CLIENTE.nombre%TYPE:=UPPER('&NOMBRE_CLIENTE:');
V_Apellido_Cliente CLIENTE.apellido%TYPE:=UPPER('&APELLIDO_CLIENTE:');
V_Placa COCHE.placa%TYPE:=UPPER('&PLACA_COCHE:');
V_Fecha_Fin RESERVA.fechafinal%TYPE:=('&FECHA_FINAL:');
V_Cod_Reserva RESERVA.codigo%TYPE;
V_Cod_Agencia AGENCIA.codigo%TYPE;
V_Ced_Cliente CLIENTE.cedula%TYPE;

BEGIN
SELECT codigo INTO V_Cod_Agencia FROM agencia WHERE UPPER(nombre) LIKE %V_Agencia%;

SELECT cedula INTO V_Ced_Cliente FROM cliente WHERE UPPER(nombre) LIKE %V_Nombre_Cliente% AND UPPER(apellido) LIKE %V_Apellido_Cliente%;

SELECT placa INTO v_Placa FROM coche WHERE UPPER(placa) LIKE V_Placa;

SELECT MAX(TO_NUMBER(codigo))+1 INTO V_Cod_Reserva FROM reserva for update;
Update reserva set codigo=v_cod_reserva;
Insert into reserva values (v_cod_reserva; v_Cod_Agencia, v_Ced_Cliente, v_placa, sysdate, to_date(v_fecha_fin));

commit;
end;
/

Avísame si te vale, un saludo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Ayuda con un bloque SQL

Publicado por Oscar (4 intervenciones) el 23/11/2010 08:36:10
Hola Patricia!

Te agradezco la ayuda, pero tengo un par de inquietudes. La primera; en el ejercicio 1 al contar las filas de la tabla reserva, Hace falta la palabra INTO? es decir, Select placaCoche, count(*) INTO cuantos From reserva.

Mi segunda inquietud es que en el ejercicio 2 usas FOR UPDATE en la consulta del código de la reserva y tengo entendido que esto se usa en los cursores de actualización y allí no hay declarado ninguno.

PD: Aún no lo he podido probar porque debo importar la BD del servidor de la Universidad en la que estudio.

PD2: Me gustaría saber si me puedes dar un e-mail para contactarte en caso de tener otras inquietudes, porque a través del foro es mucho más demorado obtener una respuesta. Muchas gracias por tu colaboración :)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Ayuda con un bloque SQL

Publicado por Patricia Dávila (3 intervenciones) el 23/11/2010 11:16:57
Hola Oscar,
Hasta donde yo pueda te echo una mano porque también estoy como tú, soy novatilla.

Tus dudas,

La primera; en el ejercicio 1 al contar las filas de la tabla reserva, Hace falta la palabra INTO? es decir, Select placaCoche, count(*) INTO cuantos From reserva.

- Si es un PL, sí, es obligatorio. Si es en SQL no lo es porque en SQL no se puede poner "into".

Mi segunda inquietud es que en el ejercicio 2 usas FOR UPDATE en la consulta del código de la reserva y tengo entendido que esto se usa en los cursores de actualización y allí no hay declarado ninguno.

- Está deducido del código, si no se hace aparecen problemas de concurrencia en donde se hace necesario proteger a la variable de otras ejecuciones del mismo código a la vez. El for update se usa para prevenir problemas de concurrencia pero viendo el código que has puesto es mejor que nada porque tal y como lo tienes planteado sólo funcionaría si siempre se asegura que sólo un usuario ejecuta el código a la vez.

Espero pueda aclarar tus dudas, si me equivoco, por favor que alguien me corrija.

Un saludo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar