PDA

Ver la Versión Completa : Consultas anidadas en procedimientos almacenados


Choclito
15-07-2004, 16:34:08
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:


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
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


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
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


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