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

Problema con Store Procedure en PostgreSQL

Estas en el tema de Problema con Store Procedure en PostgreSQL en el foro de Bases de Datos General en Foros del Web. Tengo un problema al crear la siguiente función en PL/PGSQL. Este es el Script que utilizo para crearlo: Código: CREATE FUNCTION sch_general."doSelect"(IN tabla text) RETURNS ...
  #1 (permalink)  
Antiguo 07/10/2009, 02:50
Avatar de jgabrielsinner10  
Fecha de Ingreso: octubre-2008
Mensajes: 26
Antigüedad: 15 años, 6 meses
Puntos: 0
Problema con Store Procedure en PostgreSQL

Tengo un problema al crear la siguiente función en PL/PGSQL. Este es el Script que utilizo para crearlo:

Código:
CREATE FUNCTION sch_general."doSelect"(IN tabla text) RETURNS RECORD AS
$BODY$
DECLARE
	registro RECORD%ROWTYPE;
BEGIN
	FOR registro IN EXECUTE 'select * from ' || tabla  LOOP
		RETURN NEXT registro;
	END LOOP;
	RETURN;
END;
$BODY$
LANGUAGE 'sql' VOLATILE;
ALTER FUNCTION sch_general."doSelect"(IN text) OWNER TO postgres;
Pero, me devuelve que hay un error en la linea 4 "near RECORD%ROWTYPE;" la cual contiene esto:

Código:
registro RECORD%ROWTYPE;
Estoy tratando de realizar algo parecido a un "SELECT * FROM tabla" pero, con SP y para cualquier "tabla" y traerme todos los registros de la misma.

Si Alguien me puede ayudar estaé siempre muy agradecido, de verdad es urgente.

Última edición por jgabrielsinner10; 07/10/2009 a las 02:56
  #2 (permalink)  
Antiguo 07/10/2009, 09:13
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: Problema con Store Procedure en PostgreSQL

2 cosas jgabrielsinner10

1. Cuando utilizas una función con language 'sql', No es posible realizar sentencias for ni procedimientos de programación. Por eso es recomendable hacer uso de language 'plpgsql'.
2. Para retornar un record es necesario especificar los campos que se mostraran en la tabla que quieres ejecutar al momento de ejecutarla.

te dejo un ejemplo.

Código sql:
Ver original
  1. pruebas=> \d sueldos
  2.               Tabla ½public.sueldos╗
  3.       Columna      |     Tipo     | Modificadores
  4. -------------------+--------------+---------------
  5.  id                | INTEGER      |
  6.  categoria         | text         |
  7.  unidad_tributaria | NUMERIC(6,2) |
  8.  
  9. pruebas=> \d sueldos1
  10.                      Tabla ½public.sueldos1╗
  11.       Columna      |            Tipo             | Modificadores
  12. -------------------+-----------------------------+---------------
  13.  id                | INTEGER                     |
  14.  categoria         | text                        |
  15.  unidad_tributaria | text                        |
  16.  id_peti           | INTEGER                     |
  17.  fecha             | TIMESTAMP WITHOUT TIME zone | DEFAULT now()
  18.  tipo_servicio     | text                        |
  19.  factracion        | text                        |
  20.  
  21. pruebas=> CREATE OR REPLACE FUNCTION consulta(text) RETURNS setof record
  22. pruebas-> AS
  23. pruebas-> $body$
  24. pruebas$> DECLARE
  25. pruebas$> registro record;
  26. pruebas$> SQL text;
  27. pruebas$> BEGIN
  28. pruebas$> SQL = 'select *from ' || $1;
  29. pruebas$> FOR registro IN EXECUTE SQL
  30. pruebas$> loop
  31. pruebas$> RETURN NEXT registro;
  32. pruebas$> END loop;
  33. pruebas$> RETURN;
  34. pruebas$> END;
  35. pruebas$> $body$ LANGUAGE 'plpgsql' VOLATILE;
  36. CREATE FUNCTION
  37. pruebas=> SELECT *FROM consulta('sueldos') AS t(a INTEGER, b text, c NUMERIC);
  38.  a | b |  c
  39. ---+---+------
  40.  6 | B | 1.12
  41.  3 | A | 1.00
  42.  7 | C | 1.37
  43.  6 | B | 1.12
  44.  3 | A | 1.00
  45.  7 | C | 1.37
  46. (6 filas)
  47.  
  48. pruebas=> SELECT *FROM consulta('sueldos1') AS t(a INTEGER, b text, c text, d INTEGER, e TIMESTAMP,f text, g text);
  49.  a | b |  c   | d  |            e            |      f       |     g
  50. ---+---+------+----+-------------------------+--------------+-----------
  51.  6 | B | 1.12 | 20 | 2009-03-16 11:26:57.453 | sin facturar | seleccion
  52.  3 | A | 1.00 | 20 | 2009-03-16 11:26:57.453 | sin facturar | seleccion
  53.  7 | C | 1.37 | 20 | 2009-03-16 11:26:57.453 | sin facturar | seleccion
  54.  6 | B | 1.12 | 20 | 2009-03-16 11:26:57.453 | sin facturar | seleccion
  55.  3 | A | 1.00 | 20 | 2009-03-16 11:26:57.453 | sin facturar | seleccion
  56.  7 | C | 1.37 | 20 | 2009-03-16 11:26:57.453 | sin facturar | seleccion
  57.  8 | A | 1    | 18 | 2009-03-27 08:22:44.953 | facturado    | seleccion
  58. (7 filas)

saludos
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #3 (permalink)  
Antiguo 07/10/2009, 09:37
Avatar de jgabrielsinner10  
Fecha de Ingreso: octubre-2008
Mensajes: 26
Antigüedad: 15 años, 6 meses
Puntos: 0
Respuesta: Problema con Store Procedure en PostgreSQL

Oye full gracias por explicarme eso.

Ahora tengo otro Error

Tengo esta tabla tbl_ciudades

Código:
CREATE TABLE sch_general.tbl_ciudades
(
  ciudades_id serial NOT NULL,
  ciudades_descripcion character varying(20) NOT NULL,
  estados_id integer NOT NULL,
  CONSTRAINT tbl_ciudades_pkey PRIMARY KEY (ciudades_id),
  CONSTRAINT tbl_ciudades_estados_id_fkey FOREIGN KEY (estados_id)
      REFERENCES sch_general.tbl_estados (estados_id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)
Ya creé el SP sin problemas.

Código:
CREATE OR REPLACE FUNCTION sch_general."doSelect"(tabla text)
  RETURNS SETOF record AS
$BODY$
DECLARE
	registro RECORD;
	sql TEXT;
BEGIN
	sql = 'SELECT * FROM ' || $1;
	FOR registro IN EXECUTE sql  LOOP
		RETURN NEXT registro;
	END LOOP;
	RETURN;
END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE
  COST 100
  ROWS 1000;
ALTER FUNCTION sch_general."doSelect"(text) OWNER TO postgres;
Ahora cuando llamo al SP de esta forma:

Código:
SELECT * FROM sch_general."doSelect"('sch_general.tbl_ciudades') AS tbl_ciudades(ciudades_id INTEGER, ciudades_descripcion text, estados_id numeric);
Me lanza este error:

RROR: wrong record type supplied in RETURN NEXT
CONTEXTO: PL/pgSQL function "doSelect" line 7 at RETURN NEXT

********** Error **********

ERROR: wrong record type supplied in RETURN NEXT
SQL state: 42804
Context: PL/pgSQL function "doSelect" line 7 at RETURN NEXT


Ah! Otra Cosa Brother.

Código:
	BEGIN
		IF ciudad_id == 0 THEN
			IF estado_id == 0 THEN
				-- Consulta General de Todos los Registros
				SELECT INTO ciudades * FROM sch_general.tbl_ciudades;
			ELSE
				-- Consulta por FK
				SELECT INTO ciudades * FROM sch_general.tbl_ciudades WHERE sch_general.tbl_ciudades.estados_id = estado_id;
			END IF;
		ELSE
			-- Consulta por PK
			SELECT INTO ciudades * FROM sch_general.tbl_ciudades WHERE sch_general.tbl_ciudades.ciudades_id = ciudad_id;
		END IF;
	END;
Me dá unos errores en las comparaciones... NO entiendo cómo hacer las comparaciones (IF) de datos en SP de Postgres.

Última edición por jgabrielsinner10; 07/10/2009 a las 10:15
  #4 (permalink)  
Antiguo 07/10/2009, 10:26
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: Problema con Store Procedure en PostgreSQL

Prueba lanzandolo así:
Código sql:
Ver original
  1. SELECT * FROM sch_general."doSelect"('sch_general.tbl_ciudades') AS tbl(ciudades_id serial, ciudades_descripcion CHARACTER VARYING, estados_id INTEGER);

Cita:
Me dá unos errores en las comparaciones... NO entiendo cómo hacer las comparaciones (IF) de datos en SP de Postgres.
Las comparaciones no son con doble = como en varios lenguajes. Basta con:

Código sql:
Ver original
  1. IF ciudad_id = 0 THEN
  2.             IF estado_id = 0 THEN
  3.                 -- Consulta General de Todos los Registros
  4.                 SELECT INTO ciudades * FROM sch_general.tbl_ciudades;
  5.             ELSE
  6.                 -- Consulta por FK
  7.                 SELECT INTO ciudades * FROM sch_general.tbl_ciudades WHERE sch_general.tbl_ciudades.estados_id = estado_id;
  8.             END IF;
  9.         ELSE
  10.             -- Consulta por PK
  11.             SELECT INTO ciudades * FROM sch_general.tbl_ciudades WHERE sch_general.tbl_ciudades.ciudades_id = ciudad_id;
  12.         END IF;

saludos
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #5 (permalink)  
Antiguo 07/10/2009, 11:48
Avatar de jgabrielsinner10  
Fecha de Ingreso: octubre-2008
Mensajes: 26
Antigüedad: 15 años, 6 meses
Puntos: 0
De acuerdo Respuesta: Problema con Store Procedure en PostgreSQL

OOOOKA Thanks Very much Brother. Me ayudaste full con esto estoy en un proyecto en el que tengo que hacer uso de SP y no he encontrado una buena documentación para esto. Muchas gracias de nuevo.
  #6 (permalink)  
Antiguo 07/10/2009, 12:13
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: Problema con Store Procedure en PostgreSQL

Este es un gran problema de plpgsql. Con este lenguaje se pueden hacer grandes cosas, pero toda la información la he encontrado en foros como estos.

Debería haber un manual de referencia dedicado a plpgsql.

Te recomiendo si tienes nuevas dudas, postearlas en el subforo de postgresql, ya que los duros de postgres poco se pasan por este foro.

saludos
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
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 08:29.