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

Procedimiento con campos de select variables

Estas en el tema de Procedimiento con campos de select variables en el foro de PostgreSQL en Foros del Web. HOLA. tengo un procedimiento almacenado, el cual puede ejecutar 3 query diferentes, estos a su ves son variables en los campos del select. el procedimiento ...
  #1 (permalink)  
Antiguo 25/11/2009, 09:09
Avatar de webness  
Fecha de Ingreso: enero-2009
Ubicación: BOGOTA
Mensajes: 312
Antigüedad: 15 años, 10 meses
Puntos: 5
Procedimiento con campos de select variables

HOLA.


tengo un procedimiento almacenado, el cual puede ejecutar 3 query diferentes, estos a su ves son variables en los campos del select. el procedimiento debe retorna los registros del query que ejecute.

colocar el nombre de la tabla en el tipo de retorno no puedo, porque la conuslta segun el query es a una tabla distinta.

por ahora tengo cree un tipo con la maxima cantidad de datos del select que retorno, lo cual me obligo a usar comodines en los otros querys.

es decir que si en el tipo creado tengo los campos A,B,C,D,E,F Y en el query Uno retorno todos los campos, pero en el query dos retorno SOLO A,B,C,'','',F Y EN el tercer query el select queda por ejemplo asi A,'',B,C,D,'',F.

ADJUNTO EL PROCEDIMIENTO REAL

Código SQL:
Ver original
  1. CREATE OR REPLACE FUNCTION p_get_blocks_count(INTEGER, VARCHAR,VARCHAR,VARCHAR,VARCHAR) RETURNS SETOF t_blocks_count AS $BODY$
  2. DECLARE
  3.     FILTER              ALIAS FOR $1;  
  4.     area_list           ALIAS FOR $2;
  5.     city_list           ALIAS FOR $3;
  6.     socioeconomic_list  ALIAS FOR $4;
  7.     country             ALIAS FOR $5;
  8.    
  9.     sql_query VARCHAR;
  10.     query_result t_blocks_count;
  11. BEGIN
  12.     IF FILTER = 1 THEN
  13.         sql_query := '  SELECT  country_name,region_name,city_name,locale_name,locale_code,$$''$$,$$''$$,socioeconomic_status,city_code,total
  14.                         FROM    conteo_manzanas_localidad_'||country||'
  15.                         WHERE   locale_code             IN ('||area_list||') AND
  16.                                 city_code               IN ('||city_list||') AND
  17.                                 socioeconomic_status    IN ('||socioeconomic_list||')';
  18.         FOR query_result IN EXECUTE sql_query LOOP RETURN NEXT query_result;
  19.         END LOOP;          
  20.     ELSE
  21.         IF FILTER = 2 THEN
  22.             sql_query := '  SELECT  country_name,region_name,city_name,locale_name,locale_code,neighborhood_name,neighborhood_code,socioeconomic_status,city_code,total
  23.                             FROM    conteo_manzanas_barrio_'||country||'
  24.                             WHERE   neighborhood_code       IN ('||area_list||') AND
  25.                                     city_code               IN ('||city_list||') AND
  26.                                     socioeconomic_status    IN ('||socioeconomic_list||')';
  27.             FOR query_result IN EXECUTE sql_query LOOP RETURN NEXT query_result;
  28.             END LOOP;
  29.         ELSE
  30.             sql_query := '  SELECT  country_name,region_name,city_name,$$''$$,$$''$$,$$''$$,$$''$$,socioeconomic_status,city_code,total
  31.                             FROM    conteo_manzanas_municipio_'||country||'
  32.                             WHERE   city_code               IN ('||city_list||') AND
  33.                                     socioeconomic_status    IN ('||socioeconomic_list||')';
  34.             FOR query_result IN EXECUTE sql_query LOOP RETURN NEXT query_result;
  35.             END LOOP;
  36.         END IF;
  37.     END IF;
  38.     RETURN;
  39. END $BODY$
  40. LANGUAGE plpgsql;

existe alguna forma de evitar eso?
  #2 (permalink)  
Antiguo 25/11/2009, 09:46
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 9 meses
Puntos: 360
Respuesta: Procedimiento con campos de select variables

Sin mirar muy a detalle el procedimiento

No podrías mandar el nombre de la tabla como parametro? Y en otro campo, mandar la cantidad que retorna el select?

Quedaría un procedimiento mucho mas limpio.

saludos
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #3 (permalink)  
Antiguo 25/11/2009, 10:07
Avatar de webness  
Fecha de Ingreso: enero-2009
Ubicación: BOGOTA
Mensajes: 312
Antigüedad: 15 años, 10 meses
Puntos: 5
Respuesta: Procedimiento con campos de select variables

pues la idea es dejar el codigo php lo mas limpio posible, puesto que no quiero calcular en el php el nombre de la tabla. puesto que la idea es que otros programadores utilicen mis metodos php para obtener simplemente la informacion, es decir, la idea es que ellos hagan

$obj->getData($param);
  #4 (permalink)  
Antiguo 25/11/2009, 12:07
Avatar de xdrtas  
Fecha de Ingreso: junio-2008
Ubicación: Venezuela
Mensajes: 97
Antigüedad: 16 años, 5 meses
Puntos: 13
Respuesta: Procedimiento con campos de select variables

Hola webness, mira, no entiendo muy bien, pero por qué no usas SETOF record en vez de un tipo hecho por tí? El Record se construye automáticamente con los campos que tenga la consulta. Si tu primera consulta tiene A,B,C, así será el record devuelto, si la segunda consulta es A,D,E,F así será tu record para esa segunda consulta.

Un ejemplo de una consulta que tengo hecha para una página web que estoy haciendo:

Código sql:
Ver original
  1. CREATE OR REPLACE FUNCTION fpaginartabla(num SMALLINT, tam INTEGER, reg INTEGER)
  2.   RETURNS SETOF record AS
  3. $BODY$
  4.         DECLARE
  5.             datos record;
  6.         BEGIN
  7.             IF (num = 1) THEN
  8.                 FOR datos IN
  9.                     SELECT "alb_ID", "alb_Titulo" FROM "Album" ORDER BY "alb_ID" LIMIT tam OFFSET reg
  10.                 LOOP
  11.                     RETURN NEXT datos;
  12.                 END LOOP;
  13.             END IF;
  14.             IF (num = 2) THEN
  15.                 FOR datos IN
  16.                     SELECT "usr_ID", ("usr_Nombre" || ' ' || "usr_Apellido")::VARCHAR AS "Nombre", "usr_Alias" FROM "Usuario" WHERE "usr_Nivel" < 3 ORDER BY "usr_ID" LIMIT tam OFFSET reg
  17.                 LOOP
  18.                     RETURN NEXT datos;
  19.                 END LOOP;
  20.             END IF;
  21.         END;
  22.     $BODY$
  23.   LANGUAGE 'plpgsql' VOLATILE
  24.   COST 100
  25.   ROWS 1000;
  26. ALTER FUNCTION fpaginartabla(SMALLINT, INTEGER, INTEGER) OWNER TO postgres;

Si te fijas, la primera consulta me devuelve dos parámetros y la segunda consulta me devuelve tres, y no tengo que agregar comodines.

O quieres hacer otra cosa?

Espero tu respuesta, saludos.
  #5 (permalink)  
Antiguo 25/11/2009, 14:19
Avatar de webness  
Fecha de Ingreso: enero-2009
Ubicación: BOGOTA
Mensajes: 312
Antigüedad: 15 años, 10 meses
Puntos: 5
Respuesta: Procedimiento con campos de select variables

Cuantas filas de resultados devuelven tus consultas?

Al inicio intente con RECORD pero no me funciono. tiene algo que ver si retorno una fila o varias?. de todos modos voy a ensayar a ver que pasa
  #6 (permalink)  
Antiguo 25/11/2009, 14:35
Avatar de webness  
Fecha de Ingreso: enero-2009
Ubicación: BOGOTA
Mensajes: 312
Antigüedad: 15 años, 10 meses
Puntos: 5
Respuesta: Procedimiento con campos de select variables

me salio el suiguiente error

Error de SQL:

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

En la declaración:
SELECT * FROM p_test(1, $$122,121,120,119,118$$ ,$$739$$,$$'2','3','4'$$,'co')
  #7 (permalink)  
Antiguo 25/11/2009, 14:50
Avatar de xdrtas  
Fecha de Ingreso: junio-2008
Ubicación: Venezuela
Mensajes: 97
Antigüedad: 16 años, 5 meses
Puntos: 13
Respuesta: Procedimiento con campos de select variables

Cita:
Iniciado por webness Ver Mensaje
Cuantas filas de resultados devuelven tus consultas?

Al inicio intente con RECORD pero no me funciono. tiene algo que ver si retorno una fila o varias?. de todos modos voy a ensayar a ver que pasa
Desde PHP mando a que me devuelva 10 registros o tuplas por parámetro, y por supuesto eso lo puedo cambiar para que me devuelva desde 1 hasta N usando el comando LIMIT.

Ese error que te salió es porque no creaste la lista de retorno de la consulta. Te pongo el ejemplo con mi función:

Código sql:
Ver original
  1. //Este ejemplo es con la función que puse yo para que me entiendas:
  2. SELECT * fpaginartabla(1::SMALLINT, 10, 0) AS (id INTEGER, tit VARCHAR);
  3.  
  4. SELECT * fpaginartabla(2::SMALLINT, 10, 0) AS (id INTEGER, nombre VARCHAR, alias VARCHAR);
Como puedes ver en tu consulta a la función "SELECT * FROM p_test(1, $$122,121,120,119,118$$ ,$$739$$,$$'2','3','4'$$,'co')" te falta el listado con los valores de retorno de tu consulta.

En mi llamada a función, el 10 es el número de tuplas que quiero que me traiga la función desde la primera que es el 0.

Espero tu respuesta.
  #8 (permalink)  
Antiguo 25/11/2009, 15:07
Avatar de webness  
Fecha de Ingreso: enero-2009
Ubicación: BOGOTA
Mensajes: 312
Antigüedad: 15 años, 10 meses
Puntos: 5
Respuesta: Procedimiento con campos de select variables

Me sale un error

ERROR: wrong record type supplied in RETURN NEXT
CONTEXT: PL/pgSQL function "p_test" line 12 at return next

En la declaración:
SELECT *
FROM p_test(1, $$122,121,120,119,118$$ ,$$739$$,$$'2','3','4'$$,'co') AS
(country_name varchar ,
region_name varchar,
city_name varchar,
locale_name varchar,
locale_code integer,
socioeconomic_status varchar,
city_code integer,
total integer) ;
  #9 (permalink)  
Antiguo 25/11/2009, 15:08
Avatar de webness  
Fecha de Ingreso: enero-2009
Ubicación: BOGOTA
Mensajes: 312
Antigüedad: 15 años, 10 meses
Puntos: 5
Respuesta: Procedimiento con campos de select variables

Me sale un error

ERROR: wrong record type supplied in RETURN NEXT
CONTEXT: PL/pgSQL function "p_test" line 12 at return next

En la declaración:
SELECT *
FROM p_test(1, $$122,121,120,119,118$$ ,$$739$$,$$'2','3','4'$$,'co') AS
(country_name varchar ,
region_name varchar,
city_name varchar,
locale_name varchar,
locale_code integer,
socioeconomic_status varchar,
city_code integer,
total integer) ;
  #10 (permalink)  
Antiguo 25/11/2009, 15:20
Avatar de webness  
Fecha de Ingreso: enero-2009
Ubicación: BOGOTA
Mensajes: 312
Antigüedad: 15 años, 10 meses
Puntos: 5
Respuesta: Procedimiento con campos de select variables

Ya era problema mio con los tipos de datos.

Ahora bien, esta solucion que me planteas le he aprendido, pero no la voy a implementar, pues lo que quiero es ocultarle al programador muchos de talles de la base datos. Igual me sirve para otras cosas que tengo que hacer.
  #11 (permalink)  
Antiguo 25/11/2009, 15:26
Avatar de xdrtas  
Fecha de Ingreso: junio-2008
Ubicación: Venezuela
Mensajes: 97
Antigüedad: 16 años, 5 meses
Puntos: 13
Respuesta: Procedimiento con campos de select variables

Cita:
Iniciado por webness Ver Mensaje
ERROR: wrong record type supplied in RETURN NEXT
CONTEXT: PL/pgSQL function "p_test" line 12 at return next
Este error es porque uno de los tipos de datos devueltos por la consulta no coincide con la definición que el pusiste en el listado "AS(country_name varchar ,
region_name varchar,
city_name varchar,
locale_name varchar,
locale_code integer,
socioeconomic_status varchar,
city_code integer,
total integer
);"

Puede que uno de los parámetros devuelto en la consulta no sea varchar, sino char o text, o que no sea integer sino bigint o smallint. Revisa bien Te estás acercando.
  #12 (permalink)  
Antiguo 25/11/2009, 15:30
Avatar de webness  
Fecha de Ingreso: enero-2009
Ubicación: BOGOTA
Mensajes: 312
Antigüedad: 15 años, 10 meses
Puntos: 5
Respuesta: Procedimiento con campos de select variables

Ya era problema mio con los tipos de datos.

Ahora bien, esta solucion que me planteas le he aprendido.

Pero lastimosamente no la voy a implementar, pues lo que quiero es ocultarle al programador muchos de talles de la base datos. Igual quiero facilitarle la vida al desarrollador, puesto que de la forma no ideal, llamo de una forma muy facil el procedimiento desde php

Código PHP:
$this->strSQL =   "SELECT * FROM p_get_blocks_count(".$params[0].", $$".$params[1]."$$ ,$$".$params[2]."$$,$$".$params[3]."$$,'co')"


Igual me sirve para otras cosas que tengo que hacer.

THANKS

Última edición por webness; 25/11/2009 a las 15:36
  #13 (permalink)  
Antiguo 25/11/2009, 15:43
Avatar de xdrtas  
Fecha de Ingreso: junio-2008
Ubicación: Venezuela
Mensajes: 97
Antigüedad: 16 años, 5 meses
Puntos: 13
Respuesta: Procedimiento con campos de select variables

Cita:
Iniciado por webness Ver Mensaje
Pero lastimosamente no la voy a implementar, pues lo que quiero es ocultarle al programador muchos de talles de la base datos.
No entiendo exactamente que es lo que quieres hacer, o mejor dicho, que es lo que quieres ocultar, sin embargo me alegro de haberte ayudado aunque sea en algo.

Yo uso este tipo de funciones y todo queda oculto, ya que el programador nunca ve como es la función internamente,(o sea, no conoce la estructura de la tabla), solo sabe los valores que tiene que insertar y cuales son los que le va a devolver la función, evidentemente, el programador necesita saber cuales son esos datos para trabajar con ellos.

Pero ya sabes, cualquier cosa y si se puede por aqui estamos para ayudar en lo que se pueda, saludos y suerte con lo que buscas.

  #14 (permalink)  
Antiguo 25/11/2009, 15:59
Avatar de xdrtas  
Fecha de Ingreso: junio-2008
Ubicación: Venezuela
Mensajes: 97
Antigüedad: 16 años, 5 meses
Puntos: 13
Respuesta: Procedimiento con campos de select variables

Cita:
Iniciado por webness Ver Mensaje
Igual quiero facilitarle la vida al desarrollador, puesto que de la forma no ideal, llamo de una forma muy facil el procedimiento desde php

Código PHP:
$this->strSQL =   "SELECT * FROM p_get_blocks_count(".$params[0].", $$".$params[1]."$$ ,$$".$params[2]."$$,$$".$params[3]."$$,'co')"
Y no quieres que llamen al procedimiento almacenado directamente?
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 12:08.