Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   Stored Procedure con un If después de un Select (https://www.clubdelphi.com/foros/showthread.php?t=46790)

gluglu 08-08-2007 17:44:58

Stored Procedure con un If después de un Select
 
Hola Compañer@s !

No me aclaro con esto de los Stored Procedures en Interbase.

Quiero más o menos crear esta Stored Procedure :
Código SQL [-]
begin
  Select BOJ.BOOKINGNO
  from BOOKINGS_OBJECTS BOJ
  left join BOOKINGS BO
    on BO.BOOKINGNO = BOJ.BOOKINGNO
  where
    BOJ.BUILDINGNO = :"BUILDING_NO" and
    BOJ.OBJECTNO = :"OBJECT_NO" and 
    BOJ.DATETO <= :"DATE_SP" and
    BO.STATUS = 3
    Into BOOK_NO;
  if (not BOJ.BOOKINGNO is Null) then 
    SUSPEND;
  else begin
    Select BOJ.BOOKINGNO 
    from BOOKINGS_OBJECTS BOJ
    left join BOOKINGS BO
      on BO.BOOKINGNO = BOJ.BOOKINGNO
    where
      BOJ.BUILDINGNO = :"BUILDING_NO" and
      BOJ.OBJECTNO = :"OBJECTNO" and
      BOJ.DATEFROM >= :"DATE_SP" and
      BOJ.DATETO <= :"DATE_SP" and
      BO.STATUS <= 2
      Into BOOK_NO;
  end
end

Pero me da error en la línea subrayada.

Lo que quiero hacer es buscar un registro determinado, pero si no cumple la condición que pregunto después (en mi caso concreto, si se produjo un EOF del primer Select), ejecutar otro Select diferente con otras condiciones para devolver un valor diferente.

Lo que necesito es saber como preguntar si el primer Select encontró o no un registro (o varios), y en caso contrario (preguntando por EOF ? :confused:), sjecutar el segundo Select con otras condiciones.

Gracias por vuestra ayuda.

eduarcol 08-08-2007 17:54:26

Aclarando que no tengo mucha experiencia en el asunto de los SP yo trabajo directamente sobre la variable del resultado

o sea if (not Book_No is Null) then

pues quizas sea una idea sin sentido....

ArdiIIa 08-08-2007 17:56:17

En un procedure el suspend devuelve los resultados

en este caso
Código SQL [-]
FOR Select BOJ.BOOKINGNO
  from BOOKINGS_OBJECTS BOJ
  left join BOOKINGS BO
    on BO.BOOKINGNO = BOJ.BOOKINGNO
  where
    BOJ.BUILDINGNO = :"BUILDING_NO" and
    BOJ.OBJECTNO = :"OBJECT_NO" and 
    BOJ.DATETO <= :"DATE_SP" and
    BO.STATUS = 3
    Into BOOK_NO 
do suspend;
Te devolvería los registros encontrados y además creo que el concepto del EOF es esquivoco.
FOR xxx DO hace que accedas a cada valor del select y tal como cita eduarcol has de preguntar a los valores hallados (:BOOk_NO)

gluglu 08-08-2007 18:03:51

Gracias a los dos por responder.

De momento me lo acepta así
Código SQL [-]
begin
  for Select BOJ.BOOKINGNO
  from BOOKINGS_OBJECTS BOJ
  left join BOOKINGS BO
    on BO.BOOKINGNO = BOJ.BOOKINGNO
  where
    BOJ.BUILDINGNO = :"BUILDING_NO" and
    BOJ.OBJECTNO = :"OBJECT_NO" and 
    BOJ.DATETO <= :"DATE_SP" and
    BO.STATUS = 3
    Into BOOK_NO
  do
    begin
      if (not :"BOOK_NO" is Null) then
        SUSPEND;
      else begin
        Select BOJ2.BOOKINGNO 
        from BOOKINGS_OBJECTS BOJ2
        left join BOOKINGS BO2
          on BO2.BOOKINGNO = BOJ2.BOOKINGNO
        where
          BOJ2.BUILDINGNO = :"BUILDING_NO" and
          BOJ2.OBJECTNO = :"OBJECT_NO" and
          BOJ2.DATEFROM >= :"DATE_SP" and
          BOJ2.DATETO <= :"DATE_SP" and
          BO2.STATUS <= 2
          Into BOOK_NO;
      end
    end
end

Ahora tengo que probar si me hace correctamente lo que quiero obtener :p

ArdiIIa 08-08-2007 18:06:03

Código SQL [-]
 else begin
        FOR Select BOJ2.BOOKINGNO 
        from BOOKINGS_OBJECTS BOJ2
        left join BOOKINGS BO2
          on BO2.BOOKINGNO = BOJ2.BOOKINGNO
        where
          BOJ2.BUILDINGNO = :"BUILDING_NO" and
          BOJ2.OBJECTNO = :"OBJECT_NO" and
          BOJ2.DATEFROM >= :"DATE_SP" and
          BOJ2.DATETO <= :"DATE_SP" and
          BO2.STATUS <= 2
          Into BOOK_NO
        do suspend;
      end

Si la primera falla, devuelveme lo segundo....

gluglu 08-08-2007 18:38:22

Pues no, no funciona ! :mad:

Debo entender que para aquellos registros que no cumplen la primera condición, al hacer un Select, si no encuentra ninguno que cumpla la condición impuesta para el primer Select, (repito) al no haber ningún registro válido, tampoco me ejecuta el bloque de después dentro del 'Do', ese decir, el siguiente Select con la nueva condición.

Es por ello, que para los registros que cumplen la primera condición si me devuelve el valor que quiero correctamente, pero para los que no cumplen esa primera condición no me devuelve nada (=null) ya que de hecho no entra al segundo Select.

Por ello os pido de nuevo ayudita ! :o

gluglu 08-08-2007 18:46:59

Ya parece que sí funciona ! :D

Código SQL [-]
begin

  Select BOJ.BOOKINGNO
  from BOOKINGS_OBJECTS BOJ
  left join BOOKINGS BO
    on BO.BOOKINGNO = BOJ.BOOKINGNO
  where
    BOJ.BUILDINGNO = :"BUILDING_NO" and
    BOJ.OBJECTNO = :"OBJECT_NO" and 
    BOJ.DATETO <= :"DATE_SP" and
    BO.STATUS = 3
    Into BOOK_NO;

  if (not :"BOOK_NO" is Null) then
    SUSPEND;
  else begin

    Select BOJ2.BOOKINGNO 
    from BOOKINGS_OBJECTS BOJ2
    left join BOOKINGS BO2
      on BO2.BOOKINGNO = BOJ2.BOOKINGNO
    where
      BOJ2.BUILDINGNO = :"BUILDING_NO" and
      BOJ2.OBJECTNO = :"OBJECT_NO" and
      BOJ2.DATEFROM <= :"DATE_SP" and
      BOJ2.DATETO >= :"DATE_SP" and
      BO2.STATUS <= 2
      Into BOOK_NO;
    SUSPEND;

  end

end

ArdiIIa 08-08-2007 19:16:57

Creo que es tu caso, que solamente un registro va acumplir la condición... ??

Si fueran varios registros los que cumplieran la condición, seguramente tal como lo dejas (SIN EL FOR) te petará...

Haz la prueba.

gluglu 08-08-2007 19:23:34

Gracias ArdiIIa.

Creo que me estoy complicando bastante la vida por querelo hacer en un SP y no por código con diferentes preguntas y consultas.

Ya me dí cuenta de lo que dices y lo estuve pensando. En teoría sólo debería devolver un registro. Pero al momento de ahora no te puedo decir al 100% seguro si finalmente puede darse también que existan más de un registro.

Si fuera así, tampoco lo tengo solucionado porque el SP anterior no me funciona correctamente por lo que expliqué. Si no existe ningún registro que cumpla la primera condición, no entra siquiera al segundo Select. No sé como se podría hacer eso.

Y ahora añado una nueva duda en relación con este tema. Todo esto viene porque en mi Select principal, dentro del programa, tendría que hacer esto :

Código SQL [-]
Select OJ.OBJECTNO,
(Select BOOK_NO from RACK_OBTAIN_BOOKINGNO(OJ.BUILDINGNO, OJ.OBJECTNO, '08-08-2007')) as BOOK_NO
from OBJECTS OJ
left join BOOKINGS BO
  on BO.BOOKINGNO = BOOK_NO
order by OJ.OBJECTNO
donde RACK_OBTAIN_BOOKINGNO es el SP. Ahora bien, lo que quiero es reutilizar el valor que me devuelve el SP para obtener dentro de ese mismo Select principal otros valores (en este caso dentro de la tabla BOOKINGS), de otras tablas cuyos registros deben depender del valor devuelto por el SP.

Y me dá error al intentar reutilizar el 'BOOK_NO' que me devuelve el SP.

Así que no sé cual será la mejor solución.

jhonny 08-08-2007 19:38:34

Supongo que Book:NO es un parametro de salida, entonces la cosa deberia ser, asi:

Código SQL [-]
begin

  Select BOJ.BOOKINGNO
  from BOOKINGS_OBJECTS BOJ
  left join BOOKINGS BO
    on BO.BOOKINGNO = BOJ.BOOKINGNO
  where
    BOJ.BUILDINGNO = :"BUILDING_NO" and
    BOJ.OBJECTNO = :"OBJECT_NO" and 
    BOJ.DATETO <= :"DATE_SP" and
    BO.STATUS = 3
    Into :BOOK_NO; /*Ha Book_NO le faltan esos dos puntos, para indicarle que es un parametro de salida*/

  if (not :BOOK_NO is Null) then /*Quitale esas comillas, me temo que el motor dira que nunca es Null ya que siempre es igual a "BOOK_NO"*/
    SUSPEND;
  else begin

    Select BOJ2.BOOKINGNO 
    from BOOKINGS_OBJECTS BOJ2
    left join BOOKINGS BO2
      on BO2.BOOKINGNO = BOJ2.BOOKINGNO
    where
      BOJ2.BUILDINGNO = :"BUILDING_NO" and
      BOJ2.OBJECTNO = :"OBJECT_NO" and
      BOJ2.DATEFROM <= :"DATE_SP" and
      BOJ2.DATETO >= :"DATE_SP" and
      BO2.STATUS <= 2
      Into :BOOK_NO; /*Lo mismo aca*/
    SUSPEND;

  end

end>

gluglu 08-08-2007 19:50:17

Gracias Jhonny también a tí.

Independientemente de los ':' en el BOOK_NO como parámetro de salida, funciona correctamente al menos en Interbase 7.5

Y las comillas que hay en el
Código SQL [-]
if (not :"BOOK_NO" is Null) then ...
las mete el IBConsole él solito. Si las quito y vuelvo a grabar el SP, me vuelve a poner las comillas.

Independientemente de la sintaxis que funciona de una manera u otra, no resulevo aun la problemática de qué pasa si son dos los registros que me devuelve el 1er Select, tal y como indica ArdiIIa.

Y por el contrario, tal y como indiqué, qué pasa si el primer Select no devuelve ningún registro. Pues que a mi entender no entraba a ejecutar siquiera el segundo Select.

ArdiIIa 08-08-2007 20:15:42

Vaya, creía que te había mandado otro post contestanto y ha sido que no..:D

Mira gluglu creo que esto que te voy a poner, te debería funcionar independientemente del número de registros que haya en la búsqueda... prueba y me cuentas:

Código SQL [-]

 FOR  Select BOJ.BOOKINGNO
  from BOOKINGS_OBJECTS BOJ
  left join BOOKINGS BO
    on BO.BOOKINGNO = BOJ.BOOKINGNO
  where
    BOJ.BUILDINGNO = :"BUILDING_NO" and
    BOJ.OBJECTNO = :"OBJECT_NO" and 
    BOJ.DATETO <= :"DATE_SP" and
    BO.STATUS = 3
    Into :BOOK_NO
DO
  if (:BOOK_NO is NOT Null) then 
    SUSPEND;
  else begin
FOR Select BOJ2.BOOKINGNO 
    from BOOKINGS_OBJECTS BOJ2
    left join BOOKINGS BO2
      on BO2.BOOKINGNO = BOJ2.BOOKINGNO
    where
      BOJ2.BUILDINGNO = :"BUILDING_NO" and
      BOJ2.OBJECTNO = :"OBJECT_NO" and
      BOJ2.DATEFROM <= :"DATE_SP" and
      BOJ2.DATETO >= :"DATE_SP" and
      BO2.STATUS <= 2
      Into :BOOK_NO
DO
    SUSPEND;

jhonny 08-08-2007 20:15:46

Ahhh, y ¿Porque no usar un for select?

Nota: ArdiIIa se me a adelantado, y de que manera, mejor no se podia explicar. :D


La franja horaria es GMT +2. Ahora son las 23:05:54.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi