Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Firebird e Interbase (https://www.clubdelphi.com/foros/forumdisplay.php?f=19)
-   -   Consultas anidadas en procedimientos almacenados (https://www.clubdelphi.com/foros/showthread.php?t=12413)

Choclito 15-07-2004 16:34:08

Consultas anidadas en procedimientos almacenados
 
hola foro tengo un problema con el procedimiento almacenado que tengo que es el siguiente:
COMMIT WORK;
SET TERM ^ ;
CREATE PROCEDURE DetalleTM (Des varchar (30),Codigo char (2))
RETURNS (Numero integer,TipoM varCHAR(40))
as
begin
Numero=0;
do
begin
if (:Des='Farmacia') then
begin
select DETALLE FROM TIPO_MATERIAL
WHERE CODTIPOMATERIAL IN (select CODTIPOMATERIAL
FROM TIPOMATERIAL_CUENTACONTABLE
WHERE NROCUENTACON LIKE '125%'AND NROCUENTACON IN
(SELECT NROCUENTACON FROM CUENTA_CONTABLE WHERE CODREG=:Codigo)) into :TipoM;
end
else
begin
select DETALLE FROM TIPO_MATERIAL
WHERE CODTIPOMATERIAL IN (select CODTIPOMATERIAL
FROM TIPOMATERIAL_CUENTACONTABLE
WHERE NROCUENTACON LIKE '121%' and NROCUENTACON LIKE '122%' AND NROCUENTACON IN
(SELECT NROCUENTACON FROM CUENTA_CONTABLE WHERE CODREG=:Codigo)) into :TipoM;
end
Numero=Numero+1;
suspend;
end
end^
SET TERM ; ^
COMMIT WORK;

bueno en el procedimiento almacenado quiero mostrarlos tipos de materiales que se tengan de acuerdo al area y la regional para eso tengo tres tablas tipo de mateirales(codgio,detalle), cuenta contable(codigocuenta,detalle,codigoregional),esta dos tienen una relacion * a * y entonces tengo la tabla cuenta_tipomaterial (codcuenta,codtipomaterial), en la tabla cuentacontable hay una cuenta que empieza con el 125 que es de farmacia y el resto es de alamacenes y bueno por eso hice asi mi procedimiento almacenado pero en el momento de ejecutar me sale el error de

Multiple rows in singleton select

y bueno la verdad nose que sentencia me falta o como tendria que hacer ,porfavor quisiera que me ayuden les estare muy agradecido

ruina 15-07-2004 17:21:17

prueba esto, no lo he probado asi que igual tiene algun error de sintaxis:

Código SQL [-]
COMMIT WORK;
SET TERM ^ ;
CREATE PROCEDURE DetalleTM (Des varchar (30),Codigo char (2))
RETURNS (Numero integer,TipoM varCHAR(40))
as
begin
Numero=0;
do
begin
if ( Des='Farmacia') then
begin
     FOR select DETALLE FROM TIPO_MATERIAL
     WHERE CODTIPOMATERIAL IN (select CODTIPOMATERIAL
     FROM TIPOMATERIAL_CUENTACONTABLE
     WHERE NROCUENTACON LIKE '125%'AND NROCUENTACON IN
     (SELECT NROCUENTACON FROM CUENTA_CONTABLE WHERE CODREG=:Codigo)) 
     into :TipoM; do
     begin
           numero = numero + 1;
           suspend;
      end  
end
else
begin
      FOR select DETALLE FROM TIPO_MATERIAL
     WHERE CODTIPOMATERIAL IN (select CODTIPOMATERIAL
     FROM TIPOMATERIAL_CUENTACONTABLE
     WHERE NROCUENTACON LIKE '121%' and NROCUENTACON LIKE '122%' AND NROCUENTACON  IN
     (SELECT NROCUENTACON FROM CUENTA_CONTABLE WHERE CODREG=:Codigo)) 
     into :TipoM do
     begin
            numero = numero + 1;
           suspend;
 end;
end
end^

la idea es hacer un FOR select y dentro del mismo un suspend.

guillotmarc 16-07-2004 11:45:00

Como comenta el compañero, el error te indica que hay más de un registro que cumple esas condiciones, por lo que el procedimiento almacenado no sabe que valor poner en :TipoM.

La solución que te ha indicado te va a devolver todos los valores existentes que cumplen la condición.

Saludos.

Choclito 16-07-2004 21:43:59

Ayuda
 
hola a todos del foro les cuento que hice como me dijeron pero ahora supongo
que algo mas me falta y bueno el procedimiento almacenado lo hice de esta forma :


COMMIT WORK;
SET TERM ^ ;
CREATE PROCEDURE lDetalleTM (Des varchar (30),Codigo char (2))
RETURNS (Numero integer,TipoM varCHAR(40))
as
begin
Numero=0;
if ( Des='Farmacia') then
begin
FOR select DETALLE FROM TIPO_MATERIAL
WHERE CODTIPOMATERIAL IN (select CODTIPOMATERIAL
FROM TIPOMATERIAL_CUENTACONTABLE
WHERE NROCUENTACON LIKE '125%'AND NROCUENTACON IN
(SELECT NROCUENTACON FROM CUENTA_CONTABLE WHERE CODREG=:Codigo)) into :TipoM
do
begin
numero = numero + 1;
suspend;
end
end
else
begin
FOR select DETALLE FROM TIPO_MATERIAL
WHERE CODTIPOMATERIAL IN (select CODTIPOMATERIAL
FROM TIPOMATERIAL_CUENTACONTABLE
WHERE NROCUENTACON LIKE '121%' and NROCUENTACON LIKE '122%' AND NROCUENTACON IN
(SELECT NROCUENTACON FROM CUENTA_CONTABLE WHERE CODREG=:Codigo))
into :TipoM
do
begin
numero = numero + 1;
suspend;
end
end^
SET TERM ; ^
COMMIT WORK;

pues ahora me sale el siguiente error :

Dynamic SQL Error
SQL error code = -104
Token unknown - line 12, char 80
;
esto creo que es por el ; luego de into TipoM;

luego borro el ; y me sale el siguiente error
Dynamic SQL Error
SQL error code = -104
Unexpected end of command

porfavor quisiera que me ayuden con este `procedimiento almacenado o de que forma lo puedo hacer muchas gracias

celades 17-07-2004 20:31:38

Hola
Solo veo errores tontos de los dos puntos

Código SQL [-]
CREATE PROCEDURE lDetalleTM (Des varchar (30),Codigo char (2))
RETURNS (Numero integer,TipoM varCHAR(40))
as
begin
Numero=0;
if (:Des='Farmacia') then /* faltaba :  */
begin
   FOR select DETALLE FROM TIPO_MATERIAL 
   WHERE CODTIPOMATERIAL IN (select CODTIPOMATERIAL
   FROM TIPOMATERIAL_CUENTACONTABLE
   WHERE NROCUENTACON LIKE '125%' AND NROCUENTACON IN
   (SELECT NROCUENTACON FROM CUENTA_CONTABLE wHERE CODREG=:Codigo)) into :TipoM
   do
   begin
   numero = :numero + 1; /* faltaba : */
   suspend;
   end
end
else
begin
FOR select DETALLE FROM TIPO_MATERIAL
WHERE CODTIPOMATERIAL IN (select CODTIPOMATERIAL
FROM TIPOMATERIAL_CUENTACONTABLE
WHERE NROCUENTACON LIKE '121%' and NROCUENTACON LIKE '122%' AND NROCUENTACON IN
(SELECT NROCUENTACON FROM CUENTA_CONTABLE WHERE CODREG=:Codigo))
into :TipoM
do
begin
numero = :numero + 1;  /* faltaba : */
suspend;
end
end^


Lo demas lo veo todo bien
Si no tira bien, dinos de nuevo el error

Saludos

guillotmarc 17-07-2004 21:17:47

Hola.

En la condición si faltan los dos puntos, pero no en el incremento de la variable numero. (Es un poco molesto esta excepción en la que en las asignaciones directas no hay que poner los dos puntos).

Yo tampoco veo ningún otro error en el código.

NOTA: Choclito, si encierras tu código entre cláusulas [ code ] .... [ /code ], mantendrá la identación del código, por lo que es mucho más facil de leer.

Saludos.

Choclito 18-07-2004 19:11:48

Ayuda
 
Hola nuevamente muchas gracias por la sugerencia que me hicieron pero les comento que con la ultima sugerencia ahora me sale el siguiente error:

Dynamic SQL Error
SQL error code = -104
Unexpected end of command

al depurar el codigo me indica

Dynamic SQL Error
SQL error code = -104
Token unknown - line 12, char 66
?
a la cual veo y el error seria en el parentesis antes del into :TipoM y pues la verdad nose como arreglarlo
Nuevamente les pido su ayuda o pues nose talves puede haber otra forma de hacer la consulta que quiero
Para ser mas claro tengo las siguientes tablas
TipoMaterial (CodT, Detalle)
TipoM_Cuenta (CodT,CodC)
Cuenta (CodC,Nombre,CodRegional) (hice una relacion de * a *)
Regional (CodiRegional, Nombre) (la Relacion de Cuenta y Regional es de 1 a *)

Ahora bien hay determinadas cuentas las cuales pertenecen a la seccion de farmacia,almacenes y otras, pero los tipos de materiales varian de acuerdo a la regional en la que se encuentre.
Es por eso que quiero colocar parametros de entrada como el codigo de la regional y la seccion de la cual se quiere mostrar los tipos de materiales.
Es por eso que hice de esa forma el procedimiento almacenado pero si tuvieran otra forma estare muy agradecido por las sugerencias gracias

celades 18-07-2004 22:06:33

Hola no le veia errores pero al fin vi que te falta un end final

Código SQL [-]
CREATE PROCEDURE lDetalleTM (Des varchar (30),Codigo char (2))
RETURNS (Numero integer,TipoM varCHAR(40))
as
begin
Numero=0;
if (:Des='Farmacia') then 
begin
   FOR select DETALLE FROM TIPO_MATERIAL 
   WHERE CODTIPOMATERIAL IN (select CODTIPOMATERIAL
   FROM TIPOMATERIAL_CUENTACONTABLE
   WHERE NROCUENTACON LIKE '125%' AND NROCUENTACON IN
   (SELECT NROCUENTACON FROM CUENTA_CONTABLE wHERE CODREG=:Codigo)) into :TipoM
   do
   begin
   numero = numero + 1; 
   suspend;
   end
end
else
begin
               FOR select DETALLE FROM TIPO_MATERIAL
             WHERE CODTIPOMATERIAL IN (select CODTIPOMATERIAL
              FROM TIPOMATERIAL_CUENTACONTABLE
              WHERE NROCUENTACON LIKE '121%' and NROCUENTACON             LIKE '122%' AND NROCUENTACON IN
(SELECT NROCUENTACON FROM CUENTA_CONTABLE WHERE CODREG=:Codigo))
into :TipoM
    do
    begin
     numero = numero + 1;
    suspend;
    end
  end /*Faltaba este end*/
end^

los parentesis estan bien

si te funciona la unica sugerencia es cambiar los in que son lentos por exists

Espero que funcione


La franja horaria es GMT +2. Ahora son las 15:22:41.

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