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

SQL dinamico en funcion pgsql

Estas en el tema de SQL dinamico en funcion pgsql en el foro de PostgreSQL en Foros del Web. Estimad@s: Estoy comenzando con esto del postgre y en estos minutos tengo la duda de si se pueden hacer consultas dinámicas en las funciones pgsql ...
  #1 (permalink)  
Antiguo 18/11/2009, 15:39
 
Fecha de Ingreso: agosto-2004
Mensajes: 131
Antigüedad: 20 años, 4 meses
Puntos: 2
SQL dinamico en funcion pgsql

Estimad@s:

Estoy comenzando con esto del postgre y en estos minutos tengo la duda de si se pueden hacer consultas dinámicas en las funciones pgsql

Me explico, tengo una tabla con registros y sólo quiero obtener los registros activos, la consulta seria:

Código:
SELECT * FROM tabla WHERE activo=1
Ahora, si quisiera obtener todos los registros sin importar su estado, quedaría:

Código:
SELECT * FROM tabla
Mi pregunta es, ¿Necesariamente debo hacer dos consultas distintas o puedo generar la consulta en forma dinámica mediante parámetros?. Porque por ejemplo yo podria pasarle el estado como parametro a la función y según el estado generar la consulta.

En T-SQL se puede hacer algo así
Código:
SELECT @sql = N'SELECT * FROM tabla';
IF ( @estado=1 )
BEGIN
   SELECT @sql = @sql + ' WHERE activo=1';
END
sp_executesql @sql...;
¿Es posible hacer algo así en pgsql?

Muchas gracias por su interés y ayuda.

saludos
  #2 (permalink)  
Antiguo 18/11/2009, 15:57
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 10 meses
Puntos: 360
Respuesta: SQL dinamico en funcion pgsql

si se puede.

Puedes utilizar esta función

Código sql:
Ver original
  1. CREATE OR REPLACE FUNCTION consultar_con_where(parametro_where text)
  2. RETURNS SETOF tabla_prueba AS
  3. $BODY$
  4. DECLARE
  5. fila tabla_prueba%rowtype;
  6. SQL text;
  7. BEGIN
  8. SQL = 'select id,nombre FROM tabla_prueba ' || parametro_where;
  9.  
  10.  FOR fila IN EXECUTE SQL
  11.  LOOP
  12.  RETURN NEXT fila;
  13. END LOOP;
  14. RETURN;
  15. END;
  16. $BODY$
  17. LANGUAGE 'plpgsql' VOLATILE;

Para el caso lo hago con una tabla llamada tabla_prueba
Código sql:
Ver original
  1. pruebas=> SELECT *FROM consultar_con_where('');
  2.  id | nombre
  3. ----+---------
  4.   1 | daniel
  5.   2 | sara
  6.   3 | natalia
  7. (3 filas)
  8.  
  9. pruebas=> SELECT *FROM consultar_con_where('where id=1');
  10.  id | nombre
  11. ----+--------
  12.   1 | daniel
  13. (1 fila)
  14.  
  15. pruebas=>

saludos
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #3 (permalink)  
Antiguo 19/11/2009, 05:55
 
Fecha de Ingreso: agosto-2004
Mensajes: 131
Antigüedad: 20 años, 4 meses
Puntos: 2
Respuesta: SQL dinamico en funcion pgsql

Gracias Huesos, funciona OK :)
  #4 (permalink)  
Antiguo 19/11/2009, 07:44
 
Fecha de Ingreso: agosto-2004
Mensajes: 131
Antigüedad: 20 años, 4 meses
Puntos: 2
Respuesta: SQL dinamico en funcion pgsql

Hola de nuevo Huesos

Mira al final la función me quedó así y funciona perfecto

Código:
CREATE OR REPLACE FUNCTION BuscarAreas(estado boolean) RETURNS SETOF tbl_area_tematica AS $$
DECLARE
	datos tbl_area_tematica%rowtype;
	sql TEXT := 'SELECT area_tem_id, area_tem_nombre, area_tem_activa FROM tbl_area_tematica';
	sqlEstado TEXT;
BEGIN
	IF ( estado=TRUE ) THEN
		sql = sql || ' WHERE area_tem_activa=TRUE';
	ELSE
		sql = sql || ' WHERE area_tem_activa=FALSE';
	END IF;
	FOR datos IN EXECUTE sql LOOP
		RETURN NEXT datos;
	END LOOP;
	RETURN;
END
$$ LANGUAGE plpgsql VOLATILE;

Sin embargo estuve mirando la documentación y encontré la función EXECUTE.. INTO...USING, la intenté usar pero me funcionaba sólo al no pasar el parámetro, si le paso el parámetro no me devuelve nada. Había quedado así:

Código:
CREATE OR REPLACE FUNCTION BuscarAreas(estado boolean) RETURNS SETOF tbl_area_tematica AS $$
DECLARE
	datos tbl_area_tematica%rowtype;
	sql TEXT := 'SELECT area_tem_id, area_tem_nombre, area_tem_activa FROM tbl_area_tematica';
	sqlEstado TEXT;
BEGIN
	IF ( estado<>NULL ) THEN
		sql = sql || ' WHERE area_tem_activa=$1';
	END IF;
	EXECUTE sql INTO datos USING estado;
END
$$ LANGUAGE plpgsql VOLATILE;
Desplegué la consulta por pantalla y estaba OK, lo único que se me ocurre es que no se haya realizado bien el reemplazo del parámetro, que según entiendo es la fortaleza de usar EXECUTE

¿Algún comentario con respecto a la última función?

Saludos y muchas gracias de nuevo

Rodrigo

PD: ¿Cómo posteo el código en formato SQL? (como lo pusiste en la respuesta), gracias
  #5 (permalink)  
Antiguo 19/11/2009, 07:50
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 10 meses
Puntos: 360
Respuesta: SQL dinamico en funcion pgsql

Has hecho un gran trabajo rprogged

COn respecto al codigo SQL, fijate en el espacio donde escribimos los mensajes un icono con el simbolo #. Si te paras sobre el, verás que dice highlight.

Si quieres postear código sql, simplemente señalas el codigo y presionas este botón. El te abre una pequeña ventana donde pones sql y listo. También sirve para código php, mysql, csharp y no se cuales mas.

saludos
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #6 (permalink)  
Antiguo 19/11/2009, 08:18
 
Fecha de Ingreso: agosto-2004
Mensajes: 131
Antigüedad: 20 años, 4 meses
Puntos: 2
Respuesta: SQL dinamico en funcion pgsql

jaja no es nada, muy por el contrario si algo bueno he hecho en este caso te lo debo a ti

gracias por la explicación acerca del código, al final no logré que me funcionara la función con el EXECUTE INTO USING asi que termine inclinandome por la primera versión que anda perfecto

en fin, seguiré investigando

gracias de nuevo
  #7 (permalink)  
Antiguo 19/11/2009, 14:54
 
Fecha de Ingreso: agosto-2004
Mensajes: 131
Antigüedad: 20 años, 4 meses
Puntos: 2
Respuesta: SQL dinamico en funcion pgsql

Me respondo yo mismo, en el tema del execute me faltaba el ciclo para recuperar los datos y devolverlos, finalmente queda así

Código PGSQL:
Ver original
  1. CREATE OR REPLACE FUNCTION BuscarAreas(estado boolean) RETURNS SETOF tbl_area_tematica AS $$
  2. DECLARE
  3.     datos tbl_area_tematica%rowtype;
  4.     sql TEXT := 'SELECT area_tem_id, area_tem_nombre, area_tem_activa FROM tbl_area_tematica';
  5.     sqlEstado TEXT;
  6. BEGIN
  7.     IF ( estado<>NULL ) THEN
  8.         sql = sql || ' WHERE area_tem_activa=$1';
  9.     END IF;
  10.     FOR datos IN EXECUTE sql USING estado LOOP
  11.                RETURN NEXT datos;
  12.     END LOOP;
  13.     RETURN;
  14. END
  15. $$ LANGUAGE plpgsql VOLATILE;

Por si a alguien le sirve.

Saludos
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 02:21.