Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » PostgreSQL »

Que tengo mal en este Procedimiento almacenado ? 8.2

Estas en el tema de Que tengo mal en este Procedimiento almacenado ? 8.2 en el foro de PostgreSQL en Foros del Web. Buenas tardes de nuevo. Bueno, en realidad son dos preguntas, jejeje. Es que estoy empezando con PostgreSQL y bueno... vengo de SQL Server asi que ...
  #1 (permalink)  
Antiguo 07/12/2007, 08:00
 
Fecha de Ingreso: junio-2003
Ubicación: Asturias
Mensajes: 2.429
Antigüedad: 20 años, 10 meses
Puntos: 7
Que tengo mal en este Procedimiento almacenado ? 8.2

Buenas tardes de nuevo.

Bueno, en realidad son dos preguntas, jejeje. Es que estoy empezando con PostgreSQL y bueno... vengo de SQL Server asi que algún que otro problemilla estoy teniendo.

Tengo un Procedimiento almacenado, el cual quiero que me devuelva unos registros de una tabla, ok, perfecto. El problema es que ademas de los registros de esa tabla, tambien quiero que me devuelva otros dos, que estan en otras dos tablas (Es decir, un simple inner join).

Los registros a recuperar son de las tablas tusuarios y tprovincias y tpaises. Pero claro, como veran en el SP la sintaxis esta mal, estoy seguro, pero.... no sé como puedo hacerlo, por eso les pido ayuda:


Código:
CREATE OR REPLACE FUNCTION PDAMEUSUARIO(IN pdni bpchar, IN pclave bpchar) RETURNS SETOF tusuarios AS
$BODY$
DECLARE reg_tabla tusuarios;
BEGIN
	FOR reg_tabla IN SELECT cod_usuario, dni, nombre, apellido_1, apellido_2, fecha_nacimiento, 
			        tusuarios.cod_provincia, tprovincias.provincia, tusuarios.cod_pais, 
			        tpaises.pais, ciudad, codigo_postal, email, clave, telefono_movil, 
				descripcion, cod_buscar, notificarme, ver_todos
			  
				FROM tusuarios
				INNER JOIN tpaises 
					ON tpaises.cod_pais = tusuarios.cod_pais
				INNER JOIN tprovincias
					ON tprovincias.cod_provincia = tusuarios.cod_provincia

				WHERE DNI=pdni
				AND   CLAVE = pclave
	LOOP
		return next reg_tabla;
	END LOOP;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;

La llamada es simple: select * from PDAMEUSUARIO('71641951-X', 'micarlito');


Y el error que sale cuando lo ejecuto, obivamente es:
ERROR: value too long for type character varying(2)
Estado SQL:22001
Contexto:PL/pgSQL function "pdameusuario" line 3 at for over select rows


En fin, espero me puedan resolver la duda, mi intención es (SI SE PUEDE) hacerlo sin refcursor, ya que es para programar en .NET y eso me da quebraderos de cabeza.


En fin, espero puedan ayudarme, desde ya, muchas gracias por todo.

Saludos.
__________________
Charlie.
  #2 (permalink)  
Antiguo 07/12/2007, 08:18
 
Fecha de Ingreso: junio-2003
Ubicación: Asturias
Mensajes: 2.429
Antigüedad: 20 años, 10 meses
Puntos: 7
Re: Que tengo mal en este Procedimiento almacenado ? 8.2

Tambien lo intenté asi:
Código:
CREATE OR REPLACE FUNCTION PDAMEUSUARIO2(IN pdni bpchar, IN pclave bpchar) RETURNS SETOF record AS
$BODY$
DECLARE reg_fila record;
BEGIN
	FOR reg_fila IN SELECT cod_usuario, dni, nombre, apellido_1, apellido_2, fecha_nacimiento, 
			        tusuarios.cod_provincia, tprovincias.provincia, tusuarios.cod_pais, 
			        tpaises.pais, ciudad, codigo_postal, email, clave, telefono_movil, 
				descripcion, cod_buscar, notificarme, ver_todos
			  
				FROM tusuarios
				INNER JOIN tpaises 
					ON tpaises.cod_pais = tusuarios.cod_pais
				INNER JOIN tprovincias
					ON tprovincias.cod_provincia = tusuarios.cod_provincia

				WHERE DNI=pdni
				AND   CLAVE = pclave
	LOOP
		return next reg_fila;
	END LOOP;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;

El error al llamarla es:
SELECT * FROM PDAMEUSUARIO2('71641951-X', 'micarlito');

ERROR: a column definition list is required for functions returning "record"
Estado SQL:42601



Vale, en este caso entiendo que tendría que poner algo como:
SELECT * FROM PDAMEUSUARIO2('71641951-X', 'micarlito') as tabla(nombrecampo tipovalorcampo, nombrecampo2 tipovalorcampo2, etc...);

Pero... ¿No hay ninguna manera de poder realizar un select * from miPROCEDIMIENTO(parametros) y que me devuelva ya los campos que quiera, sean o no sean de una sola tabla?, vamos que si un procedimiento me devuelve 30 campos, no tenga que poner la definiciación de cada uno de ellos cada vez que queira llamarlo.
__________________
Charlie.

Última edición por chcma; 07/12/2007 a las 10:11 Razón: Concretar mas el problema.
  #3 (permalink)  
Antiguo 10/12/2007, 03:18
 
Fecha de Ingreso: febrero-2007
Mensajes: 1.292
Antigüedad: 17 años, 2 meses
Puntos: 13
Re: Que tengo mal en este Procedimiento almacenado ? 8.2

Cita:
Iniciado por chcma Ver Mensaje
Buenas tardes de nuevo.

Bueno, en realidad son dos preguntas, jejeje. Es que estoy empezando con PostgreSQL y bueno... vengo de SQL Server asi que algún que otro problemilla estoy teniendo.

Tengo un Procedimiento almacenado, el cual quiero que me devuelva unos registros de una tabla, ok, perfecto. El problema es que ademas de los registros de esa tabla, tambien quiero que me devuelva otros dos, que estan en otras dos tablas (Es decir, un simple inner join).

Los registros a recuperar son de las tablas tusuarios y tprovincias y tpaises. Pero claro, como veran en el SP la sintaxis esta mal, estoy seguro, pero.... no sé como puedo hacerlo, por eso les pido ayuda:


Código:
CREATE OR REPLACE FUNCTION PDAMEUSUARIO(IN pdni bpchar, IN pclave bpchar) RETURNS SETOF tusuarios AS
$BODY$
DECLARE reg_tabla tusuarios;
BEGIN
	FOR reg_tabla IN SELECT cod_usuario, dni, nombre, apellido_1, apellido_2, fecha_nacimiento, 
			        tusuarios.cod_provincia, tprovincias.provincia, tusuarios.cod_pais, 
			        tpaises.pais, ciudad, codigo_postal, email, clave, telefono_movil, 
				descripcion, cod_buscar, notificarme, ver_todos
			  
				FROM tusuarios
				INNER JOIN tpaises 
					ON tpaises.cod_pais = tusuarios.cod_pais
				INNER JOIN tprovincias
					ON tprovincias.cod_provincia = tusuarios.cod_provincia

				WHERE DNI=pdni
				AND   CLAVE = pclave
	LOOP
		return next reg_tabla;
	END LOOP;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;

La llamada es simple: select * from PDAMEUSUARIO('71641951-X', 'micarlito');


Y el error que sale cuando lo ejecuto, obivamente es:
ERROR: value too long for type character varying(2)
Estado SQL:22001
Contexto:PL/pgSQL function "pdameusuario" line 3 at for over select rows


En fin, espero me puedan resolver la duda, mi intención es (SI SE PUEDE) hacerlo sin refcursor, ya que es para programar en .NET y eso me da quebraderos de cabeza.


En fin, espero puedan ayudarme, desde ya, muchas gracias por todo.

Saludos.

En este caso el problema es que defines el registro para recorrer el cursor como un "tusuarios" pero luego le añades campos que no son de ese tipo, de ahi el fallo.
  #4 (permalink)  
Antiguo 10/12/2007, 03:28
 
Fecha de Ingreso: febrero-2007
Mensajes: 1.292
Antigüedad: 17 años, 2 meses
Puntos: 13
Re: Que tengo mal en este Procedimiento almacenado ? 8.2

Cita:
Vale, en este caso entiendo que tendría que poner algo como:
SELECT * FROM PDAMEUSUARIO2('71641951-X', 'micarlito') as tabla(nombrecampo tipovalorcampo, nombrecampo2 tipovalorcampo2, etc...);

Pero... ¿No hay ninguna manera de poder realizar un select * from miPROCEDIMIENTO(parametros) y que me devuelva ya los campos que quiera, sean o no sean de una sola tabla?, vamos que si un procedimiento me devuelve 30 campos, no tenga que poner la definiciación de cada uno de ellos cada vez que queira llamarlo.
Lamentablemente no se puede. Algo que por otra parte también es lógico, porque si no le dices que tipos de campos son y como se llaman, como los identificarias???

Puedes crearte un tipo para "mezclar" campos de distintas tablas, de la misma forma que usabas "tusuarios" y asi no tener que identificarlos en las llamadas, pero si tienes muchos procedimientos... esto es tedioso.

Un saludo
  #5 (permalink)  
Antiguo 03/02/2008, 10:46
 
Fecha de Ingreso: enero-2008
Mensajes: 25
Antigüedad: 16 años, 3 meses
Puntos: 0
Re: Que tengo mal en este Procedimiento almacenado ? 8.2

a ver... veamos

Última edición por bransh; 03/02/2008 a las 10:58
  #6 (permalink)  
Antiguo 03/02/2008, 10:49
 
Fecha de Ingreso: enero-2008
Mensajes: 25
Antigüedad: 16 años, 3 meses
Puntos: 0
Información Re: Que tengo mal en este Procedimiento almacenado ? 8.2

(ahi esta mas bonito )

Hola, se que es tarde, pero quizas te sirva aun! (soy nuevo en el foro)

Crea una vista con todos los campos de tu consulta:

Código:
CREATE OR REPLACE VIEW miVista AS
    SELECT cod_usuario, dni, nombre, apellido_1, apellido_2, fecha_nacimiento, 
                 tusuarios.cod_provincia, tprovincias.provincia, tusuarios.cod_pais, 
	         tpaises.pais, ciudad, codigo_postal, email, clave, telefono_movil, 
	         descripcion, cod_buscar, notificarme, ver_todos

    FROM tusuarios INNER JOIN tpaises 
    ON tpaises.cod_pais = tusuarios.cod_pais
    INNER JOIN tprovincias
    ON tprovincias.cod_provincia = tusuarios.cod_provincia
;
Y luego en el sp devolve los datos filtrados de la vista:

Código:
CREATE OR REPLACE FUNCTION pDameUsuario(IN pdni bpchar, IN pclave bpchar) RETURNS SETOF miVista AS $$
DECLARE 
    reg_tabla miVista;
BEGIN

	FOR reg_tabla IN 
            SELECT *
            FROM miVista
    	    WHERE DNI = pdni AND CLAVE = pclave
	LOOP
		RETURN NEXT reg_tabla;
	END LOOP;
END;
$$ LANGUAGE 'plpgsql' VOLATILE;
Luego la consulta es simple:

Código:
SELECT * 
FROM pDameUsuario('71641951-X', 'micarlito');
Tal cual como cuando se trata de los campos de una tabla.

Es claro que a las vistas les vas a dar las mismas restricciones que les das a las tablas en cuanto a los permisos (una de las razones de usar sp).

Salu2

Última edición por bransh; 03/02/2008 a las 10:56
  #7 (permalink)  
Antiguo 31/08/2012, 14:37
 
Fecha de Ingreso: agosto-2012
Ubicación: La Paz
Mensajes: 1
Antigüedad: 11 años, 7 meses
Puntos: 0
Respuesta: Que tengo mal en este Procedimiento almacenado ? 8.2

qtal bransh , muchas gracias por la ayuda, en verdad me ayudaste mucho busque reharto y nunca encontraba ,salud2
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 18:39.